From 640509a0de7b1f17c02cbfd91666a48b1e14ac94 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 9 Jul 2024 14:25:16 +0200 Subject: [PATCH 001/186] chore: add payloadbodies v2 to capabilities set (#1025) --- crates/rpc-types-engine/src/lib.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/rpc-types-engine/src/lib.rs b/crates/rpc-types-engine/src/lib.rs index 4534b5c773a..4e5b9c52fea 100644 --- a/crates/rpc-types-engine/src/lib.rs +++ b/crates/rpc-types-engine/src/lib.rs @@ -25,6 +25,8 @@ pub use alloy_eips::eip6110::DepositRequest as DepositRequestV1; pub use alloy_eips::eip7002::WithdrawalRequest as WithdrawalRequestV1; /// The list of all supported Engine capabilities available over the engine endpoint. +/// +/// Latest spec: Prague pub const CAPABILITIES: &[&str] = &[ "engine_forkchoiceUpdatedV1", "engine_forkchoiceUpdatedV2", @@ -41,4 +43,6 @@ pub const CAPABILITIES: &[&str] = &[ "engine_newPayloadV4", "engine_getPayloadBodiesByHashV1", "engine_getPayloadBodiesByRangeV1", + "engine_getPayloadBodiesByHashV2", + "engine_getPayloadBodiesByRangeV2", ]; From 92b0e4a92fca23639385d9857235f2eaf97ac0ba Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Tue, 9 Jul 2024 19:18:48 +0200 Subject: [PATCH 002/186] chore: fix unnameable types (#1029) --- Cargo.toml | 17 ++++++++++------- crates/contract/src/eth_call.rs | 2 ++ crates/network/src/any/mod.rs | 1 + crates/network/src/lib.rs | 2 +- crates/provider/src/fillers/mod.rs | 2 +- crates/provider/src/lib.rs | 4 ++-- crates/provider/src/provider/call.rs | 1 + crates/provider/src/provider/with_block.rs | 1 + crates/pubsub/src/lib.rs | 5 ++++- crates/rpc-client/src/batch.rs | 1 + crates/rpc-client/src/lib.rs | 2 +- crates/rpc-types-eth/src/lib.rs | 2 +- crates/serde/src/other/arbitrary_.rs | 1 + crates/serde/src/quantity.rs | 1 + crates/signer-local/src/lib.rs | 2 +- crates/transport/src/error.rs | 2 ++ crates/transport/src/lib.rs | 2 +- 17 files changed, 32 insertions(+), 16 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0831013b862..56deb3c06c1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,13 +12,16 @@ homepage = "https://github.com/alloy-rs/alloy" repository = "https://github.com/alloy-rs/alloy" exclude = ["benches/", "tests/"] -[workspace.lints] -rust.missing-debug-implementations = "warn" -rust.missing-docs = "warn" -rust.unreachable-pub = "warn" -rust.unused-must-use = "deny" -rust.rust-2018-idioms = "deny" -rustdoc.all = "warn" +[workspace.lints.rust] +missing-debug-implementations = "warn" +missing-docs = "warn" +unreachable-pub = "warn" +unused-must-use = "deny" +rust-2018-idioms = "deny" +unnameable-types = "warn" + +[workspace.lints.rustdoc] +all = "warn" [workspace.lints.clippy] all = "warn" diff --git a/crates/contract/src/eth_call.rs b/crates/contract/src/eth_call.rs index 3c601a62d20..c4dd8c227bb 100644 --- a/crates/contract/src/eth_call.rs +++ b/crates/contract/src/eth_call.rs @@ -13,6 +13,7 @@ use crate::{Error, Result}; /// Raw coder. const RAW_CODER: () = (); +#[allow(unnameable_types)] mod private { pub trait Sealed {} impl Sealed for super::Function {} @@ -121,6 +122,7 @@ where /// decoder. #[must_use = "futures do nothing unless you `.await` or poll them"] #[derive(Clone, Debug)] +#[allow(unnameable_types)] pub struct EthCallFut<'req, 'state, 'coder, D, T, N> where T: Transport + Clone, diff --git a/crates/network/src/any/mod.rs b/crates/network/src/any/mod.rs index 8cc7bf2bbe1..2acb0a1a5a1 100644 --- a/crates/network/src/any/mod.rs +++ b/crates/network/src/any/mod.rs @@ -8,6 +8,7 @@ use core::fmt; mod builder; +/// Transaction type for a catch-all network. #[derive(Debug, Clone, Copy, PartialEq, Eq)] #[doc(alias = "AnyTransactionType")] pub struct AnyTxType(u8); diff --git a/crates/network/src/lib.rs b/crates/network/src/lib.rs index e0a63d2a233..54431385f32 100644 --- a/crates/network/src/lib.rs +++ b/crates/network/src/lib.rs @@ -22,7 +22,7 @@ mod ethereum; pub use ethereum::{Ethereum, EthereumWallet}; mod any; -pub use any::AnyNetwork; +pub use any::{AnyNetwork, AnyTxType}; pub use alloy_eips::eip2718; diff --git a/crates/provider/src/fillers/mod.rs b/crates/provider/src/fillers/mod.rs index 0d0026e21cc..e2321f45ce0 100644 --- a/crates/provider/src/fillers/mod.rs +++ b/crates/provider/src/fillers/mod.rs @@ -16,7 +16,7 @@ mod nonce; pub use nonce::NonceFiller; mod gas; -pub use gas::GasFiller; +pub use gas::{GasFillable, GasFiller}; mod join_fill; pub use join_fill::JoinFill; diff --git a/crates/provider/src/lib.rs b/crates/provider/src/lib.rs index a44cc35b79a..314e1ff2494 100644 --- a/crates/provider/src/lib.rs +++ b/crates/provider/src/lib.rs @@ -6,19 +6,19 @@ #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] -#[cfg(any(test, feature = "reqwest"))] /// Type alias for a [`RootProvider`] using the [`Http`] transport and a /// reqwest client. /// /// [`Http`]: alloy_transport_http::Http +#[cfg(any(test, feature = "reqwest"))] pub type ReqwestProvider = crate::RootProvider, N>; -#[cfg(feature = "hyper")] /// Type alias for a [`RootProvider`] using the [`Http`] transport and a hyper /// client. /// /// [`Http`]: alloy_transport_http::Http +#[cfg(feature = "hyper")] pub type HyperProvider = crate::RootProvider, N>; diff --git a/crates/provider/src/provider/call.rs b/crates/provider/src/provider/call.rs index a92adef420b..c79d3944c36 100644 --- a/crates/provider/src/provider/call.rs +++ b/crates/provider/src/provider/call.rs @@ -39,6 +39,7 @@ impl serde::Serialize for EthCallParams<'_, '_, N> { /// The [`EthCallFut`] future is the future type for an `eth_call` RPC request. #[derive(Clone, Debug)] #[doc(hidden)] // Not public API. +#[allow(unnameable_types)] #[pin_project::pin_project] pub struct EthCallFut<'req, 'state, T, N, Resp, Output, Map>( EthCallFutInner<'req, 'state, T, N, Resp, Output, Map>, diff --git a/crates/provider/src/provider/with_block.rs b/crates/provider/src/provider/with_block.rs index 57e9c419059..808b72a15f6 100644 --- a/crates/provider/src/provider/with_block.rs +++ b/crates/provider/src/provider/with_block.rs @@ -56,6 +56,7 @@ where /// A future for [`RpcWithBlock`]. Simple wrapper around [`RpcCall`]. #[derive(Debug, Clone)] #[pin_project::pin_project] +#[allow(unnameable_types)] pub struct RpcWithBlockFut where T: Transport + Clone, diff --git a/crates/pubsub/src/lib.rs b/crates/pubsub/src/lib.rs index 646b00cb30c..fae9a82ac38 100644 --- a/crates/pubsub/src/lib.rs +++ b/crates/pubsub/src/lib.rs @@ -25,4 +25,7 @@ mod managers; mod service; mod sub; -pub use sub::{RawSubscription, Subscription, SubscriptionItem}; +pub use sub::{ + RawSubscription, SubAnyStream, SubResultStream, Subscription, SubscriptionItem, + SubscriptionStream, +}; diff --git a/crates/rpc-client/src/batch.rs b/crates/rpc-client/src/batch.rs index ab45295405e..7affdac2994 100644 --- a/crates/rpc-client/src/batch.rs +++ b/crates/rpc-client/src/batch.rs @@ -63,6 +63,7 @@ where #[pin_project::pin_project(project = CallStateProj)] #[derive(Debug)] +#[allow(unnameable_types)] pub enum BatchFuture { Prepared { transport: Conn, diff --git a/crates/rpc-client/src/lib.rs b/crates/rpc-client/src/lib.rs index 37148500650..10cab0096ab 100644 --- a/crates/rpc-client/src/lib.rs +++ b/crates/rpc-client/src/lib.rs @@ -22,7 +22,7 @@ mod call; pub use call::RpcCall; mod client; -pub use client::{ClientRef, RpcClient, WeakClient}; +pub use client::{ClientRef, RpcClient, RpcClientInner, WeakClient}; mod poller; pub use poller::{PollChannel, PollerBuilder}; diff --git a/crates/rpc-types-eth/src/lib.rs b/crates/rpc-types-eth/src/lib.rs index 335066e97e9..46a5f3b4bd6 100644 --- a/crates/rpc-types-eth/src/lib.rs +++ b/crates/rpc-types-eth/src/lib.rs @@ -15,7 +15,7 @@ mod block; pub use block::*; mod call; -pub use call::{Bundle, EthCallResponse, StateContext}; +pub use call::{Bundle, EthCallResponse, StateContext, TransactionIndex}; pub mod error; diff --git a/crates/serde/src/other/arbitrary_.rs b/crates/serde/src/other/arbitrary_.rs index a1cf4b2b2d0..53c92799c80 100644 --- a/crates/serde/src/other/arbitrary_.rs +++ b/crates/serde/src/other/arbitrary_.rs @@ -37,6 +37,7 @@ impl proptest::arbitrary::Arbitrary for OtherFields { /// Redefinition of `serde_json::Value` for the purpose of implementing `Arbitrary`. #[derive(Clone, Debug, arbitrary::Arbitrary)] +#[allow(unnameable_types)] pub enum ArbitraryValue { Null, Bool(bool), diff --git a/crates/serde/src/quantity.rs b/crates/serde/src/quantity.rs index 2e404ec5ada..53974b9a684 100644 --- a/crates/serde/src/quantity.rs +++ b/crates/serde/src/quantity.rs @@ -90,6 +90,7 @@ pub mod vec { } /// Private implementation details of the [`quantity`](self) module. +#[allow(unnameable_types)] mod private { #[doc(hidden)] pub trait ConvertRuint: Copy + Sized { diff --git a/crates/signer-local/src/lib.rs b/crates/signer-local/src/lib.rs index 641791f3f5d..a9a7f3e25a5 100644 --- a/crates/signer-local/src/lib.rs +++ b/crates/signer-local/src/lib.rs @@ -20,7 +20,7 @@ pub use error::LocalSignerError; #[cfg(feature = "mnemonic")] mod mnemonic; #[cfg(feature = "mnemonic")] -pub use mnemonic::MnemonicBuilder; +pub use mnemonic::{MnemonicBuilder, MnemonicBuilderError}; mod private_key; diff --git a/crates/transport/src/error.rs b/crates/transport/src/error.rs index 55b55f1bc1c..17f4eda4e1e 100644 --- a/crates/transport/src/error.rs +++ b/crates/transport/src/error.rs @@ -98,7 +98,9 @@ impl TransportErrorKind { #[derive(Debug, thiserror::Error)] #[error("HTTP error {status} with body: {body}")] pub struct HttpError { + /// The HTTP status code. pub status: u16, + /// The HTTP response body. pub body: String, } diff --git a/crates/transport/src/lib.rs b/crates/transport/src/lib.rs index eed8a694221..f892049ea76 100644 --- a/crates/transport/src/lib.rs +++ b/crates/transport/src/lib.rs @@ -18,7 +18,7 @@ pub use common::Authorization; mod error; #[doc(hidden)] pub use error::TransportErrorKind; -pub use error::{TransportError, TransportResult}; +pub use error::{HttpError, TransportError, TransportResult}; mod r#trait; pub use r#trait::Transport; From 902d847c023d9d96d63b753028731261e0871d34 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Tue, 9 Jul 2024 19:19:08 +0200 Subject: [PATCH 003/186] chore: trace output utils (#1027) --- crates/rpc-types-trace/src/parity.rs | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/crates/rpc-types-trace/src/parity.rs b/crates/rpc-types-trace/src/parity.rs index caadcd18cc9..e3c1ef4d539 100644 --- a/crates/rpc-types-trace/src/parity.rs +++ b/crates/rpc-types-trace/src/parity.rs @@ -377,14 +377,28 @@ pub enum TraceOutput { Create(CreateOutput), } -// === impl TraceOutput === - impl TraceOutput { + /// Returns the output of this trace. + pub const fn output(&self) -> &Bytes { + match self { + Self::Call(call) => &call.output, + Self::Create(create) => &create.code, + } + } + + /// Consumes the output of this trace. + pub fn into_output(self) -> Bytes { + match self { + Self::Call(call) => call.output, + Self::Create(create) => create.code, + } + } + /// Returns the gas used by this trace. - pub const fn gas_used(&self) -> U64 { + pub fn gas_used(&self) -> u64 { match self { - Self::Call(call) => call.gas_used, - Self::Create(create) => create.gas_used, + Self::Call(call) => call.gas_used.to(), + Self::Create(create) => create.gas_used.to(), } } From 617aec5f9dd5d4d6738d689cc645d4682d3d8834 Mon Sep 17 00:00:00 2001 From: Misha Date: Thu, 11 Jul 2024 01:14:40 +0700 Subject: [PATCH 004/186] feat: add rpc namespace (#994) * Implement Rpc namespace * Review comment * Dependency fix --------- Co-authored-by: Mikhail Sozin --- crates/provider/Cargo.toml | 2 ++ crates/provider/src/ext/mod.rs | 5 ++++ crates/provider/src/ext/rpc.rs | 27 ++++++++++++++++++++++ crates/rpc-types/Cargo.toml | 4 ++++ crates/rpc-types/src/lib.rs | 3 +++ crates/rpc-types/src/rpc.rs | 42 ++++++++++++++++++++++++++++++++++ 6 files changed, 83 insertions(+) create mode 100644 crates/provider/src/ext/rpc.rs create mode 100644 crates/rpc-types/src/rpc.rs diff --git a/crates/provider/Cargo.toml b/crates/provider/Cargo.toml index fb51899fb39..3fda009b291 100644 --- a/crates/provider/Cargo.toml +++ b/crates/provider/Cargo.toml @@ -32,6 +32,7 @@ alloy-rpc-types-eth.workspace = true 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 = { workspace = true, optional = true } alloy-transport-http = { workspace = true, optional = true } alloy-transport-ipc = { workspace = true, optional = true } alloy-transport-ws = { workspace = true, optional = true } @@ -98,4 +99,5 @@ debug-api = ["dep:alloy-rpc-types-trace"] engine-api = ["dep:alloy-rpc-types-engine"] net-api = [] trace-api = ["dep:alloy-rpc-types-trace"] +rpc-api = ["dep:alloy-rpc-types"] txpool-api = ["dep:alloy-rpc-types-txpool"] diff --git a/crates/provider/src/ext/mod.rs b/crates/provider/src/ext/mod.rs index 8e06ca3042e..7b6c0ffc1bf 100644 --- a/crates/provider/src/ext/mod.rs +++ b/crates/provider/src/ext/mod.rs @@ -30,6 +30,11 @@ mod trace; #[cfg(feature = "trace-api")] pub use trace::{TraceApi, TraceCallList}; +#[cfg(feature = "rpc-api")] +mod rpc; +#[cfg(feature = "rpc-api")] +pub use rpc::RpcApi; + #[cfg(feature = "txpool-api")] mod txpool; #[cfg(feature = "txpool-api")] diff --git a/crates/provider/src/ext/rpc.rs b/crates/provider/src/ext/rpc.rs new file mode 100644 index 00000000000..317a603e807 --- /dev/null +++ b/crates/provider/src/ext/rpc.rs @@ -0,0 +1,27 @@ +//! This module extends the Ethereum JSON-RPC provider with the Rpc namespace's RPC methods. +use crate::Provider; +use alloy_network::Network; +use alloy_rpc_types::RpcModules; +use alloy_transport::{Transport, TransportResult}; + +/// The rpc API provides methods to get information about the RPC server itself, such as the enabled +/// namespaces. +#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)] +pub trait RpcApi: Send + Sync { + /// Lists the enabled RPC namespaces and the versions of each. + async fn rpc_modules(&self) -> TransportResult; +} + +#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)] +impl RpcApi for P +where + N: Network, + T: Transport + Clone, + P: Provider, +{ + async fn rpc_modules(&self) -> TransportResult { + self.client().request("rpc_modules", ()).await + } +} diff --git a/crates/rpc-types/Cargo.toml b/crates/rpc-types/Cargo.toml index fedb641cde3..48288e15ac1 100644 --- a/crates/rpc-types/Cargo.toml +++ b/crates/rpc-types/Cargo.toml @@ -28,6 +28,10 @@ alloy-rpc-types-eth = { workspace = true, optional = true } alloy-rpc-types-mev = { workspace = true, optional = true } alloy-rpc-types-trace = { workspace = true, optional = true } alloy-rpc-types-txpool = { workspace = true, optional = true } +serde = { workspace = true, features = ["derive", "std"]} + +[dev-dependencies] +serde_json.workspace = true [features] default = ["eth"] diff --git a/crates/rpc-types/src/lib.rs b/crates/rpc-types/src/lib.rs index 003a3797db7..b158ec7df41 100644 --- a/crates/rpc-types/src/lib.rs +++ b/crates/rpc-types/src/lib.rs @@ -8,6 +8,9 @@ pub use alloy_serde as serde_helpers; +mod rpc; +pub use rpc::*; + #[cfg(feature = "admin")] pub use alloy_rpc_types_admin as admin; diff --git a/crates/rpc-types/src/rpc.rs b/crates/rpc-types/src/rpc.rs new file mode 100644 index 00000000000..c6f062cfa5e --- /dev/null +++ b/crates/rpc-types/src/rpc.rs @@ -0,0 +1,42 @@ +//! Types for the `rpc` API. +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +/// Represents the `rpc_modules` response, which returns the +/// list of all available modules on that transport and their version +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)] +#[serde(transparent)] +pub struct RpcModules { + module_map: HashMap, +} + +impl RpcModules { + /// Create a new instance of `RPCModules` + pub const fn new(module_map: HashMap) -> Self { + Self { module_map } + } + + /// Consumes self and returns the inner hashmap mapping module names to their versions + pub fn into_modules(self) -> HashMap { + self.module_map + } +} + +#[cfg(test)] +mod tests { + use super::*; + #[test] + fn test_parse_module_versions_roundtrip() { + let s = r#"{"txpool":"1.0","trace":"1.0","eth":"1.0","web3":"1.0","net":"1.0"}"#; + let module_map = HashMap::from([ + ("txpool".to_owned(), "1.0".to_owned()), + ("trace".to_owned(), "1.0".to_owned()), + ("eth".to_owned(), "1.0".to_owned()), + ("web3".to_owned(), "1.0".to_owned()), + ("net".to_owned(), "1.0".to_owned()), + ]); + let m = RpcModules::new(module_map); + let de_serialized: RpcModules = serde_json::from_str(s).unwrap(); + assert_eq!(de_serialized, m); + } +} From 5d8dce4b542a069d0aa2973e7705309422311de6 Mon Sep 17 00:00:00 2001 From: rakita Date: Thu, 11 Jul 2024 07:40:28 +0200 Subject: [PATCH 005/186] fix(eip7702): Add correct rlp decode/encode (#1034) * chore: add failing test * fix(eip7702): Add correct rlp decode/encode * clippy fmt * fmt * can be const --- crates/eips/src/eip7702/auth_list.rs | 98 ++++++++++++++++++++++++---- 1 file changed, 87 insertions(+), 11 deletions(-) diff --git a/crates/eips/src/eip7702/auth_list.rs b/crates/eips/src/eip7702/auth_list.rs index 11a241efae1..4e427319e36 100644 --- a/crates/eips/src/eip7702/auth_list.rs +++ b/crates/eips/src/eip7702/auth_list.rs @@ -2,8 +2,11 @@ use core::ops::Deref; #[cfg(not(feature = "std"))] use alloc::vec::Vec; -use alloy_primitives::{keccak256, Address, ChainId, B256}; -use alloy_rlp::{BufMut, Decodable, Encodable, Header, RlpDecodable, RlpEncodable}; +use alloy_primitives::{keccak256, Address, ChainId, Signature, B256}; +use alloy_rlp::{ + length_of_length, BufMut, Decodable, Encodable, Header, Result as RlpResult, RlpDecodable, + RlpEncodable, +}; /// An unsigned EIP-7702 authorization. #[derive(Debug, Clone, RlpEncodable, RlpDecodable, Eq, PartialEq)] @@ -59,34 +62,79 @@ impl Authorization { } /// Convert to a signed authorization by adding a signature. - pub const fn into_signed(self, signature: S) -> SignedAuthorization { + pub const fn into_signed(self, signature: Signature) -> SignedAuthorization { SignedAuthorization { inner: self, signature } } } /// A signed EIP-7702 authorization. -#[derive(Debug, Clone, RlpEncodable, RlpDecodable, Eq, PartialEq)] +#[derive(Debug, Clone, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct SignedAuthorization { +pub struct SignedAuthorization { #[cfg_attr(feature = "serde", serde(flatten))] inner: Authorization, - signature: S, + signature: Signature, } -impl SignedAuthorization { +impl SignedAuthorization { /// Get the `signature` for the authorization. - pub const fn signature(&self) -> &S { + pub const fn signature(&self) -> &Signature { &self.signature } /// Splits the authorization into parts. - pub fn into_parts(self) -> (Authorization, S) { + pub const fn into_parts(self) -> (Authorization, Signature) { (self.inner, self.signature) } + + /// Decodes the transaction from RLP bytes, including the signature. + fn decode_fields(buf: &mut &[u8]) -> RlpResult { + Ok(Self { + inner: Authorization { + chain_id: Decodable::decode(buf)?, + address: Decodable::decode(buf)?, + nonce: Decodable::decode(buf)?, + }, + signature: Signature::decode_rlp_vrs(buf)?, + }) + } + + /// Outputs the length of the transaction's fields, without a RLP header. + fn fields_len(&self) -> usize { + self.inner.chain_id.length() + + self.inner.address.length() + + self.inner.nonce.length() + + self.signature.rlp_vrs_len() + } +} + +impl Decodable for SignedAuthorization { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { + let header = Header::decode(buf)?; + if !header.list { + return Err(alloy_rlp::Error::UnexpectedString); + } + Self::decode_fields(buf) + } +} + +impl Encodable for SignedAuthorization { + fn encode(&self, buf: &mut dyn BufMut) { + Header { list: true, payload_length: self.fields_len() }.encode(buf); + self.inner.chain_id.encode(buf); + self.inner.address.encode(buf); + self.inner.nonce.encode(buf); + self.signature.write_rlp_vrs(buf) + } + + fn length(&self) -> usize { + let len = self.fields_len(); + len + length_of_length(len) + } } #[cfg(feature = "k256")] -impl SignedAuthorization { +impl SignedAuthorization { /// Recover the authority for the authorization. /// /// # Note @@ -104,7 +152,7 @@ impl SignedAuthorization { } } -impl Deref for SignedAuthorization { +impl Deref for SignedAuthorization { type Target = Authorization; fn deref(&self) -> &Self::Target { @@ -176,6 +224,10 @@ impl Encodable for OptionalNonce { None => Header { list: true, payload_length: 0 }.encode(out), } } + + fn length(&self) -> usize { + self.map(|nonce| nonce.length() + length_of_length(nonce.length())).unwrap_or(1) + } } impl Decodable for OptionalNonce { @@ -206,6 +258,9 @@ impl Deref for OptionalNonce { #[cfg(test)] mod tests { + use alloy_primitives::{hex, Signature}; + use core::str::FromStr; + use super::*; fn test_encode_decode_roundtrip(auth: Authorization) { @@ -243,4 +298,25 @@ mod tests { Err(alloy_rlp::Error::UnexpectedLength) ) } + + #[test] + fn test_encode_decode_signed_auth() { + let auth = SignedAuthorization { + inner: Authorization { + chain_id: 1u64, + address: Address::left_padding_from(&[6]), + nonce: Some(1u64).into(), + }, + signature: Signature::from_str("48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c8041b").unwrap(), + }; + let mut buf = Vec::new(); + auth.encode(&mut buf); + + let expected = "f85b01940000000000000000000000000000000000000006c1011ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804"; + assert_eq!(hex::encode(&buf), expected); + + let decoded = SignedAuthorization::decode(&mut buf.as_ref()).unwrap(); + assert_eq!(buf.len(), auth.length()); + assert_eq!(decoded, auth); + } } From 678617e1e4c9928b14c27477d8dd5aa25bb67f11 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Thu, 11 Jul 2024 14:12:09 +0200 Subject: [PATCH 006/186] feat: add hash for 7702 (#1037) --- crates/eips/src/eip7702/auth_list.rs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/crates/eips/src/eip7702/auth_list.rs b/crates/eips/src/eip7702/auth_list.rs index 4e427319e36..34f4bc30f02 100644 --- a/crates/eips/src/eip7702/auth_list.rs +++ b/crates/eips/src/eip7702/auth_list.rs @@ -7,9 +7,10 @@ use alloy_rlp::{ length_of_length, BufMut, Decodable, Encodable, Header, Result as RlpResult, RlpDecodable, RlpEncodable, }; +use core::hash::{Hash, Hasher}; /// An unsigned EIP-7702 authorization. -#[derive(Debug, Clone, RlpEncodable, RlpDecodable, Eq, PartialEq)] +#[derive(Debug, Clone, Hash, RlpEncodable, RlpDecodable, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct Authorization { @@ -108,6 +109,15 @@ impl SignedAuthorization { } } +impl Hash for SignedAuthorization { + fn hash(&self, state: &mut H) { + self.inner.hash(state); + self.signature.r().hash(state); + self.signature.s().hash(state); + self.signature.v().to_u64().hash(state); + } +} + impl Decodable for SignedAuthorization { fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { let header = Header::decode(buf)?; @@ -161,7 +171,7 @@ impl Deref for SignedAuthorization { } /// A recovered authorization. -#[derive(Debug, Clone, Eq, PartialEq)] +#[derive(Debug, Clone, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct RecoveredAuthorization { #[cfg_attr(feature = "serde", serde(flatten))] @@ -197,7 +207,7 @@ impl Deref for RecoveredAuthorization { /// nonce was specified (i.e. `None`). If there is 1 item, this is the same as `Some`. /// /// The wrapper type is used for RLP encoding and decoding. -#[derive(Default, Debug, Copy, Clone, Eq, PartialEq)] +#[derive(Default, Debug, Copy, Clone, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct OptionalNonce(Option); From 408ae75aa46243ae0019aa62b6facc4273015e39 Mon Sep 17 00:00:00 2001 From: Delweng Date: Thu, 11 Jul 2024 21:54:52 +0800 Subject: [PATCH 007/186] feat(genesis): rm EIP150Hash (#1039) * feat(genesis): rm eip150_hash Signed-off-by: jsvisa * fix testcase Signed-off-by: jsvisa --------- Signed-off-by: jsvisa --- crates/genesis/src/lib.rs | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/crates/genesis/src/lib.rs b/crates/genesis/src/lib.rs index d75808a8a7c..20156ad2818 100644 --- a/crates/genesis/src/lib.rs +++ b/crates/genesis/src/lib.rs @@ -255,7 +255,7 @@ impl GenesisAccount { /// Encapsulates parameters shaping network evolution and behavior. /// /// See [geth's `ChainConfig` -/// struct](https://github.com/ethereum/go-ethereum/blob/64dccf7aa411c5c7cd36090c3d9b9892945ae813/params/config.go#L349) +/// struct](https://github.com/ethereum/go-ethereum/blob/v1.14.0/params/config.go#L326) /// for the source of each field. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(default, rename_all = "camelCase")] @@ -287,10 +287,6 @@ pub struct ChainConfig { )] pub eip150_block: Option, - /// The [EIP-150](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-150.md) hard fork hash. - #[serde(skip_serializing_if = "Option::is_none")] - pub eip150_hash: Option, - /// The [EIP-155](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md) hard fork block. #[serde( skip_serializing_if = "Option::is_none", @@ -528,7 +524,6 @@ impl Default for ChainConfig { dao_fork_block: None, dao_fork_support: false, eip150_block: None, - eip150_hash: None, eip155_block: None, eip158_block: None, byzantium_block: None, @@ -987,7 +982,6 @@ mod tests { "chainId": 1337, "homesteadBlock": 0, "eip150Block": 0, - "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "eip155Block": 0, "eip158Block": 0, "byzantiumBlock": 0, @@ -1020,9 +1014,6 @@ mod tests { let expected_genesis = Genesis { config: ChainConfig { chain_id: 1337, - eip150_hash: Some( - hex!("0000000000000000000000000000000000000000000000000000000000000000").into(), - ), homestead_block: Some(0), eip150_block: Some(0), eip155_block: Some(0), @@ -1065,7 +1056,6 @@ mod tests { "chainId": 1337, "homesteadBlock": 0, "eip150Block": 0, - "eip150Hash": "0x0000000000000000000000000000000000000000000000000000000000000000", "eip155Block": 0, "eip158Block": 0, "byzantiumBlock": 0, @@ -1097,9 +1087,6 @@ mod tests { let expected_genesis = Genesis { config: ChainConfig { chain_id: 1337, - eip150_hash: Some( - hex!("0000000000000000000000000000000000000000000000000000000000000000").into(), - ), homestead_block: Some(0), eip150_block: Some(0), eip155_block: Some(0), From 1f02577f085fbbd341856d55d818dbe81c474155 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Thu, 11 Jul 2024 16:23:45 +0200 Subject: [PATCH 008/186] feat: add arbitrary to auth (#1036) * feat: add arbitrary to auth * cant use cfg because k256 can be enabled on workspace level * use macro and share fn --- crates/eips/src/eip7702/auth_list.rs | 38 ++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/crates/eips/src/eip7702/auth_list.rs b/crates/eips/src/eip7702/auth_list.rs index 34f4bc30f02..568a1deaf27 100644 --- a/crates/eips/src/eip7702/auth_list.rs +++ b/crates/eips/src/eip7702/auth_list.rs @@ -13,6 +13,10 @@ use core::hash::{Hash, Hasher}; #[derive(Debug, Clone, Hash, RlpEncodable, RlpDecodable, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] +#[cfg_attr( + any(test, feature = "arbitrary"), + derive(proptest_derive::Arbitrary, arbitrary::Arbitrary) +)] pub struct Authorization { /// The chain ID of the authorization. pub chain_id: ChainId, @@ -170,6 +174,26 @@ impl Deref for SignedAuthorization { } } +#[cfg(any(test, feature = "arbitrary"))] +impl<'a> arbitrary::Arbitrary<'a> for SignedAuthorization { + fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { + use alloy_primitives::{b256, Parity}; + + let inner = u.arbitrary::()?; + let parity = u.arbitrary::()?; + + // TODO: find an easy way to generate random signatures + let signature = Signature::from_rs_and_parity( + b256!("c569c92f176a3be1a6352dd5005bfc751dcb32f57623dd2a23693e64bf4447b0").into(), + b256!("1a891b566d369e79b7a66eecab1e008831e22daa15f91a0a0cf4f9f28f47ee05").into(), + parity, + ) + .map_err(|_| arbitrary::Error::IncorrectFormat)?; + + Ok(Self { inner, signature }) + } +} + /// A recovered authorization. #[derive(Debug, Clone, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -209,6 +233,10 @@ impl Deref for RecoveredAuthorization { /// The wrapper type is used for RLP encoding and decoding. #[derive(Default, Debug, Copy, Clone, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr( + any(test, feature = "arbitrary"), + derive(proptest_derive::Arbitrary, arbitrary::Arbitrary) +)] pub struct OptionalNonce(Option); impl OptionalNonce { @@ -268,11 +296,11 @@ impl Deref for OptionalNonce { #[cfg(test)] mod tests { + use super::*; use alloy_primitives::{hex, Signature}; + use arbitrary::Arbitrary; use core::str::FromStr; - use super::*; - fn test_encode_decode_roundtrip(auth: Authorization) { let mut buf = Vec::new(); auth.encode(&mut buf); @@ -329,4 +357,10 @@ mod tests { assert_eq!(buf.len(), auth.length()); assert_eq!(decoded, auth); } + + #[test] + fn test_arbitrary_auth() { + let mut unstructured = arbitrary::Unstructured::new(b"unstructured auth"); + let _auth = SignedAuthorization::arbitrary(&mut unstructured).unwrap(); + } } From d9d92623ba2b2fbf5db783f578f1fe25c45440f5 Mon Sep 17 00:00:00 2001 From: Dan Cline <6798349+Rjected@users.noreply.github.com> Date: Thu, 11 Jul 2024 16:24:57 -0400 Subject: [PATCH 009/186] chore: remove proptest in all crates and Arbitrary derives (#966) * chore: remove proptest in most crates and Arbitrary derives * cargo fmt rewriting static * remove other proptest derive * remove the rest of the proptest impls * make arbitraryvalue not pub * remove proptest derive from auth list --- Cargo.toml | 2 - crates/consensus/Cargo.toml | 6 -- crates/consensus/src/request.rs | 7 +-- crates/eips/Cargo.toml | 6 -- crates/eips/src/eip1898.rs | 7 +-- crates/eips/src/eip2930.rs | 28 +--------- crates/eips/src/eip4844/sidecar.rs | 3 - crates/eips/src/eip4895.rs | 7 +-- crates/eips/src/eip6110.rs | 7 +-- crates/eips/src/eip7002.rs | 7 +-- crates/eips/src/eip7251.rs | 7 +-- crates/eips/src/eip7702/auth_list.rs | 4 +- crates/rpc-types-eth/Cargo.toml | 6 -- crates/rpc-types-eth/src/log.rs | 7 +-- .../rpc-types-eth/src/transaction/receipt.rs | 7 +-- crates/rpc-types-trace/Cargo.toml | 2 - crates/serde/Cargo.toml | 6 -- crates/serde/src/other/arbitrary_.rs | 56 +------------------ crates/serde/src/other/mod.rs | 7 +-- 19 files changed, 15 insertions(+), 167 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 56deb3c06c1..112c29ba9c3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -140,8 +140,6 @@ serde_with = "3.3.0" ## misc-testing arbitrary = "1.3" assert_matches = "1.5" -proptest = { version = "1.4", default-features = false, features = ["alloc"] } -proptest-derive = { version = "0.4", default-features = false } serial_test = "3.0" similar-asserts = "1.5" tempfile = "3.10" diff --git a/crates/consensus/Cargo.toml b/crates/consensus/Cargo.toml index 1bc962c4911..a9d68626365 100644 --- a/crates/consensus/Cargo.toml +++ b/crates/consensus/Cargo.toml @@ -29,8 +29,6 @@ c-kzg = { workspace = true, features = ["serde"], optional = true } # arbitrary arbitrary = { workspace = true, features = ["derive"], optional = true } -proptest = { workspace = true, optional = true } -proptest-derive = { workspace = true, optional = true } # serde serde = { workspace = true, features = ["derive"], optional = true } @@ -41,8 +39,6 @@ alloy-eips = { workspace = true, features = ["arbitrary"] } alloy-signer.workspace = true arbitrary = { workspace = true, features = ["derive"] } -proptest = { workspace = true } -proptest-derive = { workspace = true } k256.workspace = true tokio = { workspace = true, features = ["macros"] } serde_json.workspace = true @@ -55,8 +51,6 @@ kzg = ["dep:c-kzg", "alloy-eips/kzg", "std"] arbitrary = [ "std", "dep:arbitrary", - "dep:proptest-derive", - "dep:proptest", "alloy-eips/arbitrary", ] serde = [ diff --git a/crates/consensus/src/request.rs b/crates/consensus/src/request.rs index eca98ef6153..6b6cb3211a9 100644 --- a/crates/consensus/src/request.rs +++ b/crates/consensus/src/request.rs @@ -1,5 +1,3 @@ -#![allow(unknown_lints, non_local_definitions)] // TODO: remove when proptest-derive updates - use alloy_eips::{ eip6110::DepositRequest, eip7002::WithdrawalRequest, @@ -13,10 +11,7 @@ use alloy_rlp::{Decodable, Encodable}; /// See also [EIP-7685](https://eips.ethereum.org/EIPS/eip-7685). #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[non_exhaustive] -#[cfg_attr( - any(test, feature = "arbitrary"), - derive(proptest_derive::Arbitrary, arbitrary::Arbitrary) -)] +#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(untagged))] pub enum Request { diff --git a/crates/eips/Cargo.toml b/crates/eips/Cargo.toml index 26f1c293264..07c984c2f00 100644 --- a/crates/eips/Cargo.toml +++ b/crates/eips/Cargo.toml @@ -38,8 +38,6 @@ ethereum_ssz = { workspace = true, optional = true } # arbitrary arbitrary = { workspace = true, features = ["derive"], optional = true } -proptest = { workspace = true, optional = true } -proptest-derive = { workspace = true, optional = true } [dev-dependencies] alloy-primitives = { workspace = true, features = [ @@ -48,8 +46,6 @@ alloy-primitives = { workspace = true, features = [ "arbitrary", ] } arbitrary = { workspace = true, features = ["derive"] } -proptest.workspace = true -proptest-derive.workspace = true serde_json.workspace = true [features] @@ -81,8 +77,6 @@ arbitrary = [ "std", "kzg-sidecar", "dep:arbitrary", - "dep:proptest-derive", - "dep:proptest", "alloy-primitives/arbitrary", "alloy-serde?/arbitrary", ] diff --git a/crates/eips/src/eip1898.rs b/crates/eips/src/eip1898.rs index 1ff070f2ff3..ca19ef64907 100644 --- a/crates/eips/src/eip1898.rs +++ b/crates/eips/src/eip1898.rs @@ -1,7 +1,5 @@ //! [EIP-1898]: https://eips.ethereum.org/EIPS/eip-1898 -#![allow(unknown_lints, non_local_definitions)] // TODO: remove when proptest-derive updates - use alloy_primitives::{hex::FromHexError, ruint::ParseError, BlockHash, BlockNumber, B256, U64}; use alloy_rlp::{bytes, Decodable, Encodable, Error as RlpError}; use core::{ @@ -616,10 +614,7 @@ impl From<(BlockHash, BlockNumber)> for BlockNumHash { /// Either a block hash _or_ a block number #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - any(test, feature = "arbitrary"), - derive(proptest_derive::Arbitrary, arbitrary::Arbitrary) -)] +#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] pub enum BlockHashOrNumber { /// A block hash Hash(B256), diff --git a/crates/eips/src/eip2930.rs b/crates/eips/src/eip2930.rs index 2dd78fc3ecc..094361fa152 100644 --- a/crates/eips/src/eip2930.rs +++ b/crates/eips/src/eip2930.rs @@ -2,8 +2,6 @@ //! //! [EIP-2930]: https://eips.ethereum.org/EIPS/eip-2930 -#![allow(unknown_lints, non_local_definitions)] // TODO: remove when proptest-derive updates - #[cfg(not(feature = "std"))] use alloc::vec::Vec; @@ -14,22 +12,13 @@ use core::{mem, ops::Deref}; /// A list of addresses and storage keys that the transaction plans to access. /// Accesses outside the list are possible, but become more expensive. #[derive(Clone, Debug, Default, PartialEq, Eq, Hash, RlpDecodable, RlpEncodable)] -#[cfg_attr( - any(test, feature = "arbitrary"), - derive(proptest_derive::Arbitrary, arbitrary::Arbitrary) -)] +#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct AccessListItem { /// Account addresses that would be loaded at the start of execution pub address: Address, /// Keys of storage that would be loaded at the start of execution - #[cfg_attr( - any(test, feature = "arbitrary"), - proptest( - strategy = "proptest::collection::vec(proptest::arbitrary::any::(), 0..=20)" - ) - )] // In JSON, we have to accept `null` for storage key, which is interpreted as an empty array. #[cfg_attr(feature = "serde", serde(deserialize_with = "alloy_serde::null_as_default"))] pub storage_keys: Vec, @@ -45,20 +34,9 @@ impl AccessListItem { /// AccessList as defined in EIP-2930 #[derive(Clone, Debug, Default, PartialEq, Eq, Hash, RlpDecodableWrapper, RlpEncodableWrapper)] -#[cfg_attr( - any(test, feature = "arbitrary"), - derive(proptest_derive::Arbitrary, arbitrary::Arbitrary) -)] +#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct AccessList( - #[cfg_attr( - any(test, feature = "arbitrary"), - proptest( - strategy = "proptest::collection::vec(proptest::arbitrary::any::(), 0..=20)" - ) - )] - pub Vec, -); +pub struct AccessList(pub Vec); impl From> for AccessList { fn from(list: Vec) -> Self { diff --git a/crates/eips/src/eip4844/sidecar.rs b/crates/eips/src/eip4844/sidecar.rs index 0835561dc38..33695da1629 100644 --- a/crates/eips/src/eip4844/sidecar.rs +++ b/crates/eips/src/eip4844/sidecar.rs @@ -1,7 +1,5 @@ //! EIP-4844 sidecar type -#![allow(unknown_lints, non_local_definitions)] // TODO: remove when proptest-derive updates - use crate::eip4844::{ kzg_to_versioned_hash, Blob, Bytes48, BYTES_PER_BLOB, BYTES_PER_COMMITMENT, BYTES_PER_PROOF, }; @@ -20,7 +18,6 @@ use alloc::vec::Vec; #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] #[repr(C)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(any(test, feature = "arbitrary"), derive(proptest_derive::Arbitrary))] #[doc(alias = "BlobTxSidecar")] pub struct BlobTransactionSidecar { /// The blob data. diff --git a/crates/eips/src/eip4895.rs b/crates/eips/src/eip4895.rs index c499ca6e74c..61a2e7049c7 100644 --- a/crates/eips/src/eip4895.rs +++ b/crates/eips/src/eip4895.rs @@ -2,8 +2,6 @@ //! //! [EIP-4895]: https://eips.ethereum.org/EIPS/eip-4895 -#![allow(unknown_lints, non_local_definitions)] // TODO: remove when proptest-derive updates - use alloy_primitives::{Address, U256}; use alloy_rlp::{RlpDecodable, RlpEncodable}; @@ -12,10 +10,7 @@ pub const GWEI_TO_WEI: u64 = 1_000_000_000; /// Withdrawal represents a validator withdrawal from the consensus layer. #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, RlpEncodable, RlpDecodable)] -#[cfg_attr( - any(test, feature = "arbitrary"), - derive(proptest_derive::Arbitrary, arbitrary::Arbitrary) -)] +#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "ssz", derive(ssz_derive::Encode, ssz_derive::Decode))] pub struct Withdrawal { diff --git a/crates/eips/src/eip6110.rs b/crates/eips/src/eip6110.rs index f04c02d1897..210f669fbfc 100644 --- a/crates/eips/src/eip6110.rs +++ b/crates/eips/src/eip6110.rs @@ -4,8 +4,6 @@ //! //! Provides validator deposits as a list of deposit operations added to the Execution Layer block. -#![allow(unknown_lints, non_local_definitions)] // TODO: remove when proptest-derive updates - use alloy_primitives::{address, Address, FixedBytes, B256}; use alloy_rlp::{RlpDecodable, RlpEncodable}; @@ -18,10 +16,7 @@ pub const MAINNET_DEPOSIT_CONTRACT_ADDRESS: Address = #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] #[cfg_attr(feature = "ssz", derive(ssz_derive::Encode, ssz_derive::Decode))] -#[cfg_attr( - any(test, feature = "arbitrary"), - derive(proptest_derive::Arbitrary, arbitrary::Arbitrary) -)] +#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] pub struct DepositRequest { /// Validator public key pub pubkey: FixedBytes<48>, diff --git a/crates/eips/src/eip7002.rs b/crates/eips/src/eip7002.rs index 9678efe22ff..43a11df5c06 100644 --- a/crates/eips/src/eip7002.rs +++ b/crates/eips/src/eip7002.rs @@ -2,8 +2,6 @@ //! //! See also [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002): Execution layer triggerable withdrawals -#![allow(unknown_lints, non_local_definitions)] // TODO: remove when proptest-derive updates - use alloy_primitives::{address, bytes, Address, Bytes, FixedBytes}; use alloy_rlp::{RlpDecodable, RlpEncodable}; @@ -27,10 +25,7 @@ pub const WITHDRAWAL_REQUEST_TYPE: u8 = 0x01; #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, RlpEncodable, RlpDecodable, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] -#[cfg_attr( - any(test, feature = "arbitrary"), - derive(proptest_derive::Arbitrary, arbitrary::Arbitrary) -)] +#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] pub struct WithdrawalRequest { /// Address of the source of the exit. pub source_address: Address, diff --git a/crates/eips/src/eip7251.rs b/crates/eips/src/eip7251.rs index cb72a0c5352..23406b59efb 100644 --- a/crates/eips/src/eip7251.rs +++ b/crates/eips/src/eip7251.rs @@ -2,8 +2,6 @@ //! //! See also [EIP-7251](https://eips.ethereum.org/EIPS/eip-7251): Increase the MAX_EFFECTIVE_BALANCE -#![allow(unknown_lints, non_local_definitions)] // TODO: remove when proptest-derive updates - use alloy_primitives::{address, bytes, Address, Bytes, FixedBytes}; use alloy_rlp::{RlpDecodable, RlpEncodable}; @@ -23,10 +21,7 @@ pub const CONSOLIDATION_REQUEST_TYPE: u8 = 0x02; #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] #[cfg_attr(feature = "ssz", derive(ssz_derive::Encode, ssz_derive::Decode))] -#[cfg_attr( - any(test, feature = "arbitrary"), - derive(proptest_derive::Arbitrary, arbitrary::Arbitrary) -)] +#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] pub struct ConsolidationRequest { /// Source address pub source_address: Address, diff --git a/crates/eips/src/eip7702/auth_list.rs b/crates/eips/src/eip7702/auth_list.rs index 568a1deaf27..5604508a619 100644 --- a/crates/eips/src/eip7702/auth_list.rs +++ b/crates/eips/src/eip7702/auth_list.rs @@ -15,7 +15,7 @@ use core::hash::{Hash, Hasher}; #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] #[cfg_attr( any(test, feature = "arbitrary"), - derive(proptest_derive::Arbitrary, arbitrary::Arbitrary) + derive(arbitrary::Arbitrary) )] pub struct Authorization { /// The chain ID of the authorization. @@ -235,7 +235,7 @@ impl Deref for RecoveredAuthorization { #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr( any(test, feature = "arbitrary"), - derive(proptest_derive::Arbitrary, arbitrary::Arbitrary) + derive(arbitrary::Arbitrary) )] pub struct OptionalNonce(Option); diff --git a/crates/rpc-types-eth/Cargo.toml b/crates/rpc-types-eth/Cargo.toml index 2e2b9a759e6..df87af1eec8 100644 --- a/crates/rpc-types-eth/Cargo.toml +++ b/crates/rpc-types-eth/Cargo.toml @@ -33,8 +33,6 @@ thiserror.workspace = true # arbitrary arbitrary = { version = "1.3", features = ["derive"], optional = true } -proptest = { version = "1.4", optional = true } -proptest-derive = { version = "0.4", optional = true } # jsonrpsee jsonrpsee-types = { version = "0.23", optional = true } @@ -50,16 +48,12 @@ alloy-primitives = { workspace = true, features = [ alloy-consensus = { workspace = true, features = ["std", "arbitrary"] } arbitrary = { workspace = true, features = ["derive"] } -proptest.workspace = true -proptest-derive.workspace = true rand.workspace = true similar-asserts.workspace = true [features] arbitrary = [ "dep:arbitrary", - "dep:proptest-derive", - "dep:proptest", "alloy-primitives/arbitrary", "alloy-serde/arbitrary", "alloy-eips/arbitrary", diff --git a/crates/rpc-types-eth/src/log.rs b/crates/rpc-types-eth/src/log.rs index c22aadad4e9..b1c4973cbab 100644 --- a/crates/rpc-types-eth/src/log.rs +++ b/crates/rpc-types-eth/src/log.rs @@ -1,14 +1,9 @@ -#![allow(unknown_lints, non_local_definitions)] // TODO: remove when proptest-derive updates - use alloy_primitives::{Address, BlockHash, LogData, TxHash, B256}; use serde::{Deserialize, Serialize}; /// Ethereum Log emitted by a transaction #[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)] -#[cfg_attr( - any(test, feature = "arbitrary"), - derive(proptest_derive::Arbitrary, arbitrary::Arbitrary) -)] +#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] #[serde(rename_all = "camelCase")] pub struct Log { #[serde(flatten)] diff --git a/crates/rpc-types-eth/src/transaction/receipt.rs b/crates/rpc-types-eth/src/transaction/receipt.rs index fa32de6744c..afc93c753b6 100644 --- a/crates/rpc-types-eth/src/transaction/receipt.rs +++ b/crates/rpc-types-eth/src/transaction/receipt.rs @@ -1,5 +1,3 @@ -#![allow(unknown_lints, non_local_definitions)] // TODO: remove when proptest-derive updates - use crate::Log; use alloy_consensus::{AnyReceiptEnvelope, ReceiptEnvelope, TxType}; use alloy_primitives::{Address, BlockHash, TxHash, B256}; @@ -11,10 +9,7 @@ use serde::{Deserialize, Serialize}; /// This type is generic over an inner [`ReceiptEnvelope`] which contains /// consensus data and metadata. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[cfg_attr( - any(test, feature = "arbitrary"), - derive(proptest_derive::Arbitrary, arbitrary::Arbitrary) -)] +#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] #[serde(rename_all = "camelCase")] #[doc(alias = "TxReceipt")] pub struct TransactionReceipt> { diff --git a/crates/rpc-types-trace/Cargo.toml b/crates/rpc-types-trace/Cargo.toml index 577584c4aed..7181ff4755f 100644 --- a/crates/rpc-types-trace/Cargo.toml +++ b/crates/rpc-types-trace/Cargo.toml @@ -36,7 +36,5 @@ alloy-primitives = { workspace = true, features = [ ] } arbitrary = { workspace = true, features = ["derive"] } -proptest.workspace = true -proptest-derive.workspace = true rand.workspace = true similar-asserts.workspace = true diff --git a/crates/serde/Cargo.toml b/crates/serde/Cargo.toml index e99a23090b1..8c8a74d4d1e 100644 --- a/crates/serde/Cargo.toml +++ b/crates/serde/Cargo.toml @@ -25,8 +25,6 @@ serde_json = { workspace = true, features = ["alloc"] } # arbitrary arbitrary = { version = "1.3", features = ["derive"], optional = true } -proptest = { version = "1.4", optional = true } -proptest-derive = { version = "0.4", optional = true } [dev-dependencies] alloy-primitives = { workspace = true, features = [ @@ -37,8 +35,6 @@ alloy-primitives = { workspace = true, features = [ ] } arbitrary = { workspace = true, features = ["derive"] } -proptest.workspace = true -proptest-derive.workspace = true rand.workspace = true [features] @@ -46,8 +42,6 @@ default = ["std"] std = ["alloy-primitives/std", "serde/std", "serde_json/std"] arbitrary = [ "dep:arbitrary", - "dep:proptest-derive", - "dep:proptest", "alloy-primitives/arbitrary", "std", ] diff --git a/crates/serde/src/other/arbitrary_.rs b/crates/serde/src/other/arbitrary_.rs index 53c92799c80..1b437780121 100644 --- a/crates/serde/src/other/arbitrary_.rs +++ b/crates/serde/src/other/arbitrary_.rs @@ -1,10 +1,5 @@ use crate::OtherFields; use alloc::collections::BTreeMap; -use proptest::{ - arbitrary::any, - prop_oneof, - strategy::{BoxedStrategy, Just, Strategy}, -}; #[cfg(not(feature = "std"))] use alloc::{string::String, vec::Vec}; @@ -19,26 +14,10 @@ impl arbitrary::Arbitrary<'_> for OtherFields { } } -impl proptest::arbitrary::Arbitrary for OtherFields { - type Parameters = (); - type Strategy = proptest::strategy::Map< - proptest::collection::VecStrategy<( - ::Strategy, - ::Strategy, - )>, - fn(Vec<(String, ArbitraryValue)>) -> Self, - >; - - fn arbitrary_with((): Self::Parameters) -> Self::Strategy { - proptest::collection::vec(any::<(String, ArbitraryValue)>(), 0..16) - .prop_map(|map| map.into_iter().map(|(k, v)| (k, v.into_json_value())).collect()) - } -} - /// Redefinition of `serde_json::Value` for the purpose of implementing `Arbitrary`. #[derive(Clone, Debug, arbitrary::Arbitrary)] #[allow(unnameable_types)] -pub enum ArbitraryValue { +enum ArbitraryValue { Null, Bool(bool), Number(u64), @@ -47,27 +26,6 @@ pub enum ArbitraryValue { Object(BTreeMap), } -impl proptest::arbitrary::Arbitrary for ArbitraryValue { - type Parameters = (); - type Strategy = BoxedStrategy; - - fn arbitrary_with((): Self::Parameters) -> Self::Strategy { - prop_oneof![ - Just(Self::Null), - any::().prop_map(Self::Bool), - any::().prop_map(Self::Number), - any::().prop_map(Self::String), - ] - .prop_recursive(4, 64, 16, |this| { - prop_oneof![ - 1 => proptest::collection::vec(this.clone(), 0..16).prop_map(Self::Array), - 1 => proptest::collection::btree_map(any::(), this, 0..16).prop_map(Self::Object), - ] - }) - .boxed() - } -} - impl ArbitraryValue { fn into_json_value(self) -> serde_json::Value { match self { @@ -84,15 +42,3 @@ impl ArbitraryValue { } } } - -#[cfg(test)] -mod tests { - use super::*; - - proptest::proptest!( - #[test] - fn test_arbitrary_value(value in any::()) { - let _json_value = value.into_json_value(); - } - ); -} diff --git a/crates/serde/src/other/mod.rs b/crates/serde/src/other/mod.rs index 33d62fbc98c..9f675cb1f45 100644 --- a/crates/serde/src/other/mod.rs +++ b/crates/serde/src/other/mod.rs @@ -1,7 +1,5 @@ //! Support for capturing other fields. -#![allow(unknown_lints, non_local_definitions)] // TODO: remove when proptest-derive updates - use alloc::collections::BTreeMap; use core::{ fmt, @@ -170,10 +168,7 @@ impl<'a> IntoIterator for &'a OtherFields { /// /// See [`OtherFields`] for more information. #[derive(Clone, Debug, Default, Eq, PartialEq, Serialize)] -#[cfg_attr( - any(test, feature = "arbitrary"), - derive(proptest_derive::Arbitrary, arbitrary::Arbitrary) -)] +#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] pub struct WithOtherFields { /// The inner struct. #[serde(flatten)] From dfb8650fd06fa4245bbf6201a83daac5b4e3f1b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien?= <3535019+leruaa@users.noreply.github.com> Date: Thu, 11 Jul 2024 22:25:44 +0200 Subject: [PATCH 010/186] feat: add `rpc-types-mev` feature to meta crate (#1040) --- crates/alloy/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/alloy/Cargo.toml b/crates/alloy/Cargo.toml index e920d78fb8d..a1733b0c4ef 100644 --- a/crates/alloy/Cargo.toml +++ b/crates/alloy/Cargo.toml @@ -206,6 +206,7 @@ rpc-types-engine = [ "alloy-provider?/engine-api", ] rpc-types-eth = ["rpc-types", "alloy-rpc-types?/eth"] +rpc-types-mev = ["rpc-types", "alloy-rpc-types?/mev"] rpc-types-json = ["rpc-types", "alloy-rpc-types?/jsonrpsee-types"] rpc-types-trace = [ "rpc-types", From 594a271b4ae23fdb1a961d9223ad6ef8858477a7 Mon Sep 17 00:00:00 2001 From: Dan Cline <6798349+Rjected@users.noreply.github.com> Date: Fri, 12 Jul 2024 04:43:55 -0400 Subject: [PATCH 011/186] feat: generate valid signed auth signatures (#1041) * feat: generate valid signed auth signatures * feature gate the auth arbitrary --- crates/eips/Cargo.toml | 5 ++++- crates/eips/src/eip7702/auth_list.rs | 21 +++++++++++---------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/crates/eips/Cargo.toml b/crates/eips/Cargo.toml index 07c984c2f00..4c2a1866ca5 100644 --- a/crates/eips/Cargo.toml +++ b/crates/eips/Cargo.toml @@ -39,6 +39,9 @@ ethereum_ssz = { workspace = true, optional = true } # arbitrary arbitrary = { workspace = true, features = ["derive"], optional = true } +# for signed authorization list arbitrary +k256 = { workspace = true, optional = true } + [dev-dependencies] alloy-primitives = { workspace = true, features = [ "rand", @@ -66,7 +69,7 @@ serde = [ kzg = ["kzg-sidecar", "sha2", "dep:derive_more", "dep:c-kzg", "dep:once_cell"] kzg-sidecar = ["sha2"] sha2 = ["dep:sha2"] -k256 = ["alloy-primitives/k256"] +k256 = ["alloy-primitives/k256", "dep:k256"] ssz = [ "std", "dep:ethereum_ssz", diff --git a/crates/eips/src/eip7702/auth_list.rs b/crates/eips/src/eip7702/auth_list.rs index 5604508a619..e7a6d106e83 100644 --- a/crates/eips/src/eip7702/auth_list.rs +++ b/crates/eips/src/eip7702/auth_list.rs @@ -174,21 +174,21 @@ impl Deref for SignedAuthorization { } } -#[cfg(any(test, feature = "arbitrary"))] +#[cfg(all(any(test, feature = "arbitrary"), feature = "k256"))] impl<'a> arbitrary::Arbitrary<'a> for SignedAuthorization { fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { - use alloy_primitives::{b256, Parity}; + use k256::ecdsa::{signature::hazmat::PrehashSigner, SigningKey}; + let key_bytes = u.arbitrary::<[u8; 32]>()?; + let signing_key = SigningKey::from_bytes(&key_bytes.into()) + .map_err(|_| arbitrary::Error::IncorrectFormat)?; let inner = u.arbitrary::()?; - let parity = u.arbitrary::()?; + let signature_hash = inner.signature_hash(); - // TODO: find an easy way to generate random signatures - let signature = Signature::from_rs_and_parity( - b256!("c569c92f176a3be1a6352dd5005bfc751dcb32f57623dd2a23693e64bf4447b0").into(), - b256!("1a891b566d369e79b7a66eecab1e008831e22daa15f91a0a0cf4f9f28f47ee05").into(), - parity, - ) - .map_err(|_| arbitrary::Error::IncorrectFormat)?; + let (recoverable_sig, recovery_id) = + signing_key.sign_prehash(signature_hash.as_ref()).unwrap(); + let signature = Signature::from_signature_and_parity(recoverable_sig, recovery_id) + .map_err(|_| arbitrary::Error::IncorrectFormat)?; Ok(Self { inner, signature }) } @@ -358,6 +358,7 @@ mod tests { assert_eq!(decoded, auth); } + #[cfg(feature = "k256")] #[test] fn test_arbitrary_auth() { let mut unstructured = arbitrary::Unstructured::new(b"unstructured auth"); From bec60984fc3097e91bbfbe59892a9e3ab75d03ff Mon Sep 17 00:00:00 2001 From: Delweng Date: Fri, 12 Jul 2024 17:03:08 +0800 Subject: [PATCH 012/186] fix: cargo fmt (#1044) Signed-off-by: jsvisa --- crates/eips/src/eip7702/auth_list.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/crates/eips/src/eip7702/auth_list.rs b/crates/eips/src/eip7702/auth_list.rs index e7a6d106e83..2633fd91dd3 100644 --- a/crates/eips/src/eip7702/auth_list.rs +++ b/crates/eips/src/eip7702/auth_list.rs @@ -13,10 +13,7 @@ use core::hash::{Hash, Hasher}; #[derive(Debug, Clone, Hash, RlpEncodable, RlpDecodable, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] -#[cfg_attr( - any(test, feature = "arbitrary"), - derive(arbitrary::Arbitrary) -)] +#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] pub struct Authorization { /// The chain ID of the authorization. pub chain_id: ChainId, @@ -233,10 +230,7 @@ impl Deref for RecoveredAuthorization { /// The wrapper type is used for RLP encoding and decoding. #[derive(Default, Debug, Copy, Clone, Hash, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - any(test, feature = "arbitrary"), - derive(arbitrary::Arbitrary) -)] +#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] pub struct OptionalNonce(Option); impl OptionalNonce { From bce4083ee446184c1fd105c7086c4f7eb2a83d93 Mon Sep 17 00:00:00 2001 From: zerosnacks <95942363+zerosnacks@users.noreply.github.com> Date: Fri, 12 Jul 2024 12:13:52 +0200 Subject: [PATCH 013/186] chore(deps): bump Trezor client to `=0.1.4` to fix signing bug (#1045) bump trezor client to possibly resolve signing bug https://github.com/trezor/trezor-firmware/pull/3952/files + https://github.com/foundry-rs/foundry/issues/7660#issuecomment-2169205625 --- crates/signer-trezor/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/signer-trezor/Cargo.toml b/crates/signer-trezor/Cargo.toml index 0cdf4fa8aee..eb71768d570 100644 --- a/crates/signer-trezor/Cargo.toml +++ b/crates/signer-trezor/Cargo.toml @@ -24,7 +24,7 @@ alloy-network.workspace = true alloy-primitives.workspace = true alloy-signer.workspace = true -trezor-client = { version = "=0.1.3", default-features = false, features = [ +trezor-client = { version = "=0.1.4", default-features = false, features = [ "ethereum", ] } From 8abc6071cbae6e41579c4ee21610d20848ab253c Mon Sep 17 00:00:00 2001 From: Delweng Date: Fri, 12 Jul 2024 18:47:29 +0800 Subject: [PATCH 014/186] feat(otterscan): add ots slim block and serialze OperationType to int (#1043) * fix(otterscan): add OtsSlimBlock for BlockDetails Signed-off-by: jsvisa * feat(otterscan): use serde_repr to serialize OperationType to int Signed-off-by: jsvisa * feat(otterscan): add a new function for BlockDetails Signed-off-by: jsvisa * Revert "feat(otterscan): use serde_repr to serialize OperationType to int" This reverts commit 96df6f4d53d673f8d9cf59c569ff52b3f5cf4be4. Signed-off-by: jsvisa * feat(otterscan): custom implement Serialize for OperationType Signed-off-by: jsvisa * (de)serialize to u8 Signed-off-by: jsvisa * clippy Signed-off-by: jsvisa --------- Signed-off-by: jsvisa --- crates/rpc-types-trace/src/otterscan.rs | 114 ++++++++++++++++++++++-- 1 file changed, 109 insertions(+), 5 deletions(-) diff --git a/crates/rpc-types-trace/src/otterscan.rs b/crates/rpc-types-trace/src/otterscan.rs index 85114451c9f..f5a71778cb2 100644 --- a/crates/rpc-types-trace/src/otterscan.rs +++ b/crates/rpc-types-trace/src/otterscan.rs @@ -3,12 +3,15 @@ //! //! -use alloy_primitives::{Address, Bloom, Bytes, TxHash, U256}; -use alloy_rpc_types_eth::{Block, Rich, Transaction, TransactionReceipt}; -use serde::{Deserialize, Serialize}; +use alloy_primitives::{Address, Bloom, Bytes, TxHash, B256, U256}; +use alloy_rpc_types_eth::{Block, Header, Rich, Transaction, TransactionReceipt, Withdrawal}; +use serde::{ + de::{self, Unexpected}, + Deserialize, Deserializer, Serialize, Serializer, +}; /// Operation type enum for `InternalOperation` struct -#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum OperationType { /// Operation Transfer OpTransfer = 0, @@ -20,6 +23,37 @@ pub enum OperationType { OpCreate2 = 3, } +// Implement Serialize for OperationType +impl Serialize for OperationType { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_u8(*self as u8) + } +} + +// Implement Deserialize for OperationType +impl<'de> Deserialize<'de> for OperationType { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + // Deserialize string, then parse it to u8 + let value = u8::deserialize(deserializer)?; + match value { + 0 => Ok(Self::OpTransfer), + 1 => Ok(Self::OpSelfDestruct), + 2 => Ok(Self::OpCreate), + 3 => Ok(Self::OpCreate2), + other => Err(de::Error::invalid_value( + Unexpected::Unsigned(other as u64), + &"a valid OperationType", + )), + } + } +} + /// Custom struct for otterscan `getInternalOperations` RPC response #[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct InternalOperation { @@ -83,12 +117,45 @@ impl From for OtsBlock { } } +/// Custom `Block` struct that without transactions for Otterscan responses +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct OtsSlimBlock { + /// Header of the block. + #[serde(flatten)] + pub header: Header, + /// Uncles' hashes. + #[serde(default)] + pub uncles: Vec, + /// Integer the size of this block in bytes. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub size: Option, + /// Withdrawals in the block. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub withdrawals: Option>, + /// The number of transactions in the block. + #[doc(alias = "tx_count")] + pub transaction_count: usize, +} + +impl From for OtsSlimBlock { + fn from(block: Block) -> Self { + Self { + header: block.header, + uncles: block.uncles, + size: block.size, + withdrawals: block.withdrawals, + transaction_count: block.transactions.len(), + } + } +} + /// Custom struct for otterscan `getBlockDetails` RPC response #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct BlockDetails { /// The block information with transaction count. - pub block: OtsBlock, + pub block: OtsSlimBlock, /// The issuance information for the block. pub issuance: InternalIssuance, /// The total fees for the block. @@ -105,6 +172,13 @@ impl From> for BlockDetails { } } +impl BlockDetails { + /// Create a new `BlockDetails` struct. + pub fn new(rich_block: Rich, issuance: InternalIssuance, total_fees: U256) -> Self { + Self { block: rich_block.inner.into(), issuance, total_fees } + } +} + /// Custom transaction receipt struct for otterscan `OtsBlockTransactions` struct #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] @@ -204,4 +278,34 @@ mod tests { let _receipt: OtsTransactionReceipt = serde_json::from_str(s).unwrap(); } + + #[test] + fn test_otterscan_interal_operation() { + let s = r#"{ + "type": 0, + "from": "0xea593b730d745fb5fe01b6d20e6603915252c6bf", + "to": "0xcc3d455481967dc97346ef1771a112d7a14c8f12", + "value": "0xee846f9305c00" + }"#; + let _op: InternalOperation = serde_json::from_str(s).unwrap(); + } + + #[test] + fn test_serialize_operation_type() { + assert_eq!(serde_json::to_string(&OperationType::OpTransfer).unwrap(), "0"); + assert_eq!(serde_json::to_string(&OperationType::OpSelfDestruct).unwrap(), "1"); + assert_eq!(serde_json::to_string(&OperationType::OpCreate).unwrap(), "2"); + assert_eq!(serde_json::to_string(&OperationType::OpCreate2).unwrap(), "3"); + } + + #[test] + fn test_deserialize_operation_type() { + assert_eq!(serde_json::from_str::("0").unwrap(), OperationType::OpTransfer); + assert_eq!( + serde_json::from_str::("1").unwrap(), + OperationType::OpSelfDestruct + ); + assert_eq!(serde_json::from_str::("2").unwrap(), OperationType::OpCreate); + assert_eq!(serde_json::from_str::("3").unwrap(), OperationType::OpCreate2); + } } From e3cc1ffb60112afce00d16ffd83c20f06cde31c1 Mon Sep 17 00:00:00 2001 From: Delweng Date: Sat, 13 Jul 2024 21:46:06 +0800 Subject: [PATCH 015/186] fix(admin): id in NodeInfo is string instead of B256 (#1038) * fix(admin): id in NodeInfo is string instead of B256 Signed-off-by: jsvisa * fix testcase Signed-off-by: jsvisa * apply code review Signed-off-by: jsvisa --------- Signed-off-by: jsvisa --- crates/node-bindings/src/geth.rs | 8 ++++---- crates/provider/src/ext/admin.rs | 2 +- crates/rpc-types-admin/src/admin.rs | 7 +++++-- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/crates/node-bindings/src/geth.rs b/crates/node-bindings/src/geth.rs index 79942a0f936..4c61b153a86 100644 --- a/crates/node-bindings/src/geth.rs +++ b/crates/node-bindings/src/geth.rs @@ -2,7 +2,7 @@ use crate::unused_port; use alloy_genesis::{CliqueConfig, Genesis}; -use alloy_primitives::{hex, Address, B256}; +use alloy_primitives::Address; use k256::ecdsa::SigningKey; use std::{ borrow::Cow, @@ -121,7 +121,7 @@ impl GethInstance { /// Blocks until geth adds the specified peer, using 20s as the timeout. /// /// Requires the stderr to be present in the `GethInstance`. - pub fn wait_to_add_peer(&mut self, id: B256) -> Result<(), GethInstanceError> { + pub fn wait_to_add_peer(&mut self, id: &str) -> Result<(), GethInstanceError> { let mut stderr = self.pid.stderr.as_mut().ok_or(GethInstanceError::NoStderr)?; let mut err_reader = BufReader::new(&mut stderr); let mut line = String::new(); @@ -132,8 +132,8 @@ impl GethInstance { err_reader.read_line(&mut line).map_err(GethInstanceError::ReadLineError)?; // geth ids are truncated - let truncated_id = hex::encode(&id.0[..8]); - if line.contains("Adding p2p peer") && line.contains(&truncated_id) { + let truncated_id = if id.len() > 16 { &id[..16] } else { id }; + if line.contains("Adding p2p peer") && line.contains(truncated_id) { return Ok(()); } } diff --git a/crates/provider/src/ext/admin.rs b/crates/provider/src/ext/admin.rs index 158f9598d37..b81d4701111 100644 --- a/crates/provider/src/ext/admin.rs +++ b/crates/provider/src/ext/admin.rs @@ -116,7 +116,7 @@ mod test { let added = provider2.add_peer(&node1_enode).await.unwrap(); assert!(added); - geth2.wait_to_add_peer(node1_id).unwrap(); + geth2.wait_to_add_peer(&node1_id).unwrap(); let peers = provider2.peers().await.unwrap(); assert_eq!(peers[0].enode, node1_enode); } diff --git a/crates/rpc-types-admin/src/admin.rs b/crates/rpc-types-admin/src/admin.rs index 2814f16160e..d227d117670 100644 --- a/crates/rpc-types-admin/src/admin.rs +++ b/crates/rpc-types-admin/src/admin.rs @@ -10,10 +10,13 @@ use std::{ /// This includes general information about a running node, spanning networking and protocol /// details. +/// +/// See [geth's `NodeInfo` struct](https://github.com/ethereum/go-ethereum/blob/v1.14.0/p2p/server.go#L1078) +/// for the source of each field. #[derive(Clone, Debug, Serialize, Deserialize)] pub struct NodeInfo { - /// Unique node identifier. - pub id: B256, + /// Unique node identifier(also the encryption key). + pub id: String, /// The node's user agent, containing a client name, version, OS, and other metadata. pub name: String, /// The enode URL of the connected node. From 6148d6e12bb80820ececdb54bab3c4d748a1035c Mon Sep 17 00:00:00 2001 From: JP <36560907+0xfourzerofour@users.noreply.github.com> Date: Sat, 13 Jul 2024 10:35:58 -0400 Subject: [PATCH 016/186] feat(core): update core version (#1049) --- Cargo.toml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 112c29ba9c3..76615ab2d70 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -67,11 +67,11 @@ alloy-transport-http = { version = "0.1", path = "crates/transport-http", defaul alloy-transport-ipc = { version = "0.1", path = "crates/transport-ipc", default-features = false } alloy-transport-ws = { version = "0.1", path = "crates/transport-ws", default-features = false } -alloy-core = { version = "0.7.6", default-features = false } -alloy-dyn-abi = { version = "0.7.6", default-features = false } -alloy-json-abi = { version = "0.7.6", default-features = false } -alloy-primitives = { version = "0.7.6", default-features = false } -alloy-sol-types = { version = "0.7.6", default-features = false } +alloy-core = { version = "0.7.7", default-features = false } +alloy-dyn-abi = { version = "0.7.7", default-features = false } +alloy-json-abi = { version = "0.7.7", default-features = false } +alloy-primitives = { version = "0.7.7", default-features = false } +alloy-sol-types = { version = "0.7.7", default-features = false } alloy-rlp = { version = "0.3", default-features = false } From e35703d5f67afe871d762e7eb6c9c650835c1c07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien?= <3535019+leruaa@users.noreply.github.com> Date: Sun, 14 Jul 2024 12:07:51 +0200 Subject: [PATCH 017/186] feat: impl `arbitrary` for tx structs (#1050) --- crates/consensus/src/transaction/eip1559.rs | 1 + crates/consensus/src/transaction/eip2930.rs | 1 + crates/consensus/src/transaction/eip4844.rs | 3 +++ crates/consensus/src/transaction/legacy.rs | 1 + 4 files changed, 6 insertions(+) diff --git a/crates/consensus/src/transaction/eip1559.rs b/crates/consensus/src/transaction/eip1559.rs index d195edb9444..4bd890e23c0 100644 --- a/crates/consensus/src/transaction/eip1559.rs +++ b/crates/consensus/src/transaction/eip1559.rs @@ -9,6 +9,7 @@ use alloc::vec::Vec; /// A transaction with a priority fee ([EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)). #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] #[doc(alias = "Eip1559Transaction", alias = "TransactionEip1559", alias = "Eip1559Tx")] diff --git a/crates/consensus/src/transaction/eip2930.rs b/crates/consensus/src/transaction/eip2930.rs index 85bb370c178..5cc576861d4 100644 --- a/crates/consensus/src/transaction/eip2930.rs +++ b/crates/consensus/src/transaction/eip2930.rs @@ -9,6 +9,7 @@ use alloc::vec::Vec; /// Transaction with an [`AccessList`] ([EIP-2930](https://eips.ethereum.org/EIPS/eip-2930)). #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] #[doc(alias = "Eip2930Transaction", alias = "TransactionEip2930", alias = "Eip2930Tx")] diff --git a/crates/consensus/src/transaction/eip4844.rs b/crates/consensus/src/transaction/eip4844.rs index f7ed416959f..18d2dfaae62 100644 --- a/crates/consensus/src/transaction/eip4844.rs +++ b/crates/consensus/src/transaction/eip4844.rs @@ -22,6 +22,7 @@ use alloc::vec::Vec; /// or a transaction with a sidecar, which is used when submitting a transaction to the network and /// when receiving and sending transactions during the gossip stage. #[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize))] #[cfg_attr(feature = "serde", serde(untagged))] #[doc(alias = "Eip4844TransactionVariant")] @@ -287,6 +288,7 @@ impl SignableTransaction for TxEip4844Variant { /// /// A transaction with blob hashes and max blob fee. It does not have the Blob sidecar. #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] #[doc(alias = "Eip4844Transaction", alias = "TransactionEip4844", alias = "Eip4844Tx")] @@ -704,6 +706,7 @@ impl From for TxEip4844 { /// of a `PooledTransactions` response, and is also used as the format for sending raw transactions /// through the network (eth_sendRawTransaction/eth_sendTransaction). #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] #[doc(alias = "Eip4844TransactionWithSidecar", alias = "Eip4844TxWithSidecar")] diff --git a/crates/consensus/src/transaction/legacy.rs b/crates/consensus/src/transaction/legacy.rs index c39abfbf186..4b55bea77b5 100644 --- a/crates/consensus/src/transaction/legacy.rs +++ b/crates/consensus/src/transaction/legacy.rs @@ -8,6 +8,7 @@ use alloc::vec::Vec; /// Legacy transaction. #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] #[doc(alias = "LegacyTransaction", alias = "TransactionLegacy", alias = "LegacyTx")] From ea6a44777f775b56fb7ff3c11b0af2d17ce38bdb Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Sun, 14 Jul 2024 14:23:35 +0200 Subject: [PATCH 018/186] chore: make auth mandatory in recovered auth (#1047) * chore: make auth mandatory in recovered auth * features --- crates/eips/src/eip7702/auth_list.rs | 30 ++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/crates/eips/src/eip7702/auth_list.rs b/crates/eips/src/eip7702/auth_list.rs index 2633fd91dd3..e8247202f5f 100644 --- a/crates/eips/src/eip7702/auth_list.rs +++ b/crates/eips/src/eip7702/auth_list.rs @@ -157,9 +157,11 @@ impl SignedAuthorization { /// Recover the authority and transform the signed authorization into a /// [`RecoveredAuthorization`]. - pub fn into_recovered(self) -> RecoveredAuthorization { - let authority = self.recover_authority().ok(); - RecoveredAuthorization { inner: self.inner, authority } + pub fn try_into_recovered( + self, + ) -> Result { + let authority = self.recover_authority()?; + Ok(RecoveredAuthorization { inner: self.inner, authority }) } } @@ -197,23 +199,35 @@ impl<'a> arbitrary::Arbitrary<'a> for SignedAuthorization { pub struct RecoveredAuthorization { #[cfg_attr(feature = "serde", serde(flatten))] inner: Authorization, - authority: Option
, + authority: Address, } impl RecoveredAuthorization { + /// Instantiate without performing recovery. This should be used carefully. + pub const fn new_unchecked(inner: Authorization, authority: Address) -> Self { + Self { inner, authority } + } + /// Get the `authority` for the authorization. - /// - /// If this is `None`, then the authority could not be recovered. - pub const fn authority(&self) -> Option
{ + pub const fn authority(&self) -> Address { self.authority } /// Splits the authorization into parts. - pub const fn into_parts(self) -> (Authorization, Option
) { + pub const fn into_parts(self) -> (Authorization, Address) { (self.inner, self.authority) } } +#[cfg(feature = "k256")] +impl TryFrom for RecoveredAuthorization { + type Error = alloy_primitives::SignatureError; + + fn try_from(value: SignedAuthorization) -> Result { + value.try_into_recovered() + } +} + impl Deref for RecoveredAuthorization { type Target = Authorization; From c461d6885784e45482e8b6962c4a098d0b493d57 Mon Sep 17 00:00:00 2001 From: Igor Aleksanov Date: Mon, 15 Jul 2024 14:44:39 +0400 Subject: [PATCH 019/186] fix(provider): Do not overflow LRU cache capacity in ChainStreamPoller (#1052) --- crates/provider/src/chain.rs | 77 +++++++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/crates/provider/src/chain.rs b/crates/provider/src/chain.rs index 5ffb436e1c1..7dd89f5d960 100644 --- a/crates/provider/src/chain.rs +++ b/crates/provider/src/chain.rs @@ -31,10 +31,16 @@ impl ChainStreamPoller { } pub(crate) fn new(client: WeakClient) -> Self { + Self::with_next_yield(client, NO_BLOCK_NUMBER) + } + + /// Can be used to force the poller to start at a specific block number. + /// Mostly useful for tests. + fn with_next_yield(client: WeakClient, next_yield: BlockNumber) -> Self { Self { client: client.clone(), poll_task: PollerBuilder::new(client, "eth_blockNumber", ()), - next_yield: NO_BLOCK_NUMBER, + next_yield, known_blocks: LruCache::new(BLOCK_CACHE_SIZE), _phantom: PhantomData, } @@ -106,8 +112,77 @@ impl ChainStreamPoller { } }; self.known_blocks.put(number, block); + if self.known_blocks.len() == BLOCK_CACHE_SIZE.get() { + // Cache is full, should be consumed before filling more blocks. + debug!(number, "cache full"); + break; + } } } } } } + +#[cfg(all(test, feature = "anvil-api"))] // Tests rely heavily on ability to mine blocks on demand. +mod tests { + use std::{future::Future, time::Duration}; + + use crate::{ext::AnvilApi, ProviderBuilder}; + use alloy_node_bindings::Anvil; + use alloy_primitives::U256; + use alloy_rpc_client::ReqwestClient; + + use super::*; + + fn init_tracing() { + let _ = tracing_subscriber::fmt::try_init(); + } + + async fn with_timeout(fut: T) -> T::Output { + tokio::select! { + _ = tokio::time::sleep(Duration::from_secs(1)) => panic!("Operation timed out"), + out = fut => out, + } + } + + #[tokio::test] + async fn yield_block() { + init_tracing(); + + let anvil = Anvil::new().spawn(); + + let client = ReqwestClient::new_http(anvil.endpoint_url()); + let poller: ChainStreamPoller<_, Ethereum> = + ChainStreamPoller::with_next_yield(client.get_weak(), 1); + let mut stream = Box::pin(poller.into_stream()); + + // We will also use provider to manipulate anvil instance via RPC. + let provider = ProviderBuilder::new().on_http(anvil.endpoint_url()); + provider.anvil_mine(Some(U256::from(1)), None).await.unwrap(); + + let block = with_timeout(stream.next()).await.expect("Block wasn't fetched"); + assert_eq!(block.header.number, Some(1u64)); + } + + #[tokio::test] + async fn yield_many_blocks() { + // Make sure that we can process more blocks than fits in the cache. + const BLOCKS_TO_MINE: usize = BLOCK_CACHE_SIZE.get() + 1; + + init_tracing(); + + let anvil = Anvil::new().spawn(); + + let client = ReqwestClient::new_http(anvil.endpoint_url()); + let poller: ChainStreamPoller<_, Ethereum> = + ChainStreamPoller::with_next_yield(client.get_weak(), 1); + let stream = Box::pin(poller.into_stream()); + + // We will also use provider to manipulate anvil instance via RPC. + let provider = ProviderBuilder::new().on_http(anvil.endpoint_url()); + provider.anvil_mine(Some(U256::from(BLOCKS_TO_MINE)), None).await.unwrap(); + + let blocks = with_timeout(stream.take(BLOCKS_TO_MINE).collect::>()).await; + assert_eq!(blocks.len(), BLOCKS_TO_MINE); + } +} From 7d618eed6194a5c05655e235d8ea02b90c7c6c01 Mon Sep 17 00:00:00 2001 From: Panagiotis Ganelis <50522617+PanGan21@users.noreply.github.com> Date: Mon, 15 Jul 2024 13:55:46 +0300 Subject: [PATCH 020/186] feat: add authorization list to rpc transaction and tx receipt types (#1051) * feat: add authorization list to rpc transaction and tx receipt types * fix: add default impl Co-authored-by: Matthias Seitz * fix: use signed authorization for rpc transaction type * fix: enable arbitrary and k256 features for development * fix: cargo hack fix * chore: flatten signature --------- Co-authored-by: Matthias Seitz --- crates/eips/src/eip7702/auth_list.rs | 1 + crates/rpc-types-eth/Cargo.toml | 2 ++ crates/rpc-types-eth/src/transaction/mod.rs | 29 ++++++++++++++++--- .../rpc-types-eth/src/transaction/receipt.rs | 6 ++++ 4 files changed, 34 insertions(+), 4 deletions(-) diff --git a/crates/eips/src/eip7702/auth_list.rs b/crates/eips/src/eip7702/auth_list.rs index e8247202f5f..d7ef4142639 100644 --- a/crates/eips/src/eip7702/auth_list.rs +++ b/crates/eips/src/eip7702/auth_list.rs @@ -75,6 +75,7 @@ impl Authorization { pub struct SignedAuthorization { #[cfg_attr(feature = "serde", serde(flatten))] inner: Authorization, + #[cfg_attr(feature = "serde", serde(flatten))] signature: Signature, } diff --git a/crates/rpc-types-eth/Cargo.toml b/crates/rpc-types-eth/Cargo.toml index df87af1eec8..e0bd123c1e7 100644 --- a/crates/rpc-types-eth/Cargo.toml +++ b/crates/rpc-types-eth/Cargo.toml @@ -46,6 +46,7 @@ alloy-primitives = { workspace = true, features = [ "arbitrary", ] } alloy-consensus = { workspace = true, features = ["std", "arbitrary"] } +alloy-eips = { workspace = true, features = ["arbitrary", "k256"] } arbitrary = { workspace = true, features = ["derive"] } rand.workspace = true @@ -57,6 +58,7 @@ arbitrary = [ "alloy-primitives/arbitrary", "alloy-serde/arbitrary", "alloy-eips/arbitrary", + "alloy-eips/k256", ] jsonrpsee-types = ["dep:jsonrpsee-types"] ssz = ["alloy-primitives/ssz", "alloy-eips/ssz"] diff --git a/crates/rpc-types-eth/src/transaction/mod.rs b/crates/rpc-types-eth/src/transaction/mod.rs index fb5ddb06a46..4d567e790d2 100644 --- a/crates/rpc-types-eth/src/transaction/mod.rs +++ b/crates/rpc-types-eth/src/transaction/mod.rs @@ -4,12 +4,16 @@ use alloy_consensus::{ SignableTransaction, Signed, TxEip1559, TxEip2930, TxEip4844, TxEip4844Variant, TxEnvelope, TxLegacy, TxType, }; +use alloy_eips::eip7702::SignedAuthorization; use alloy_primitives::{Address, BlockHash, Bytes, ChainId, TxHash, TxKind, B256, U256}; use alloy_serde::OtherFields; use serde::{Deserialize, Serialize}; pub use alloy_consensus::BlobTransactionSidecar; -pub use alloy_eips::eip2930::{AccessList, AccessListItem, AccessListWithGasUsed}; +pub use alloy_eips::{ + eip2930::{AccessList, AccessListItem, AccessListWithGasUsed}, + eip7702::Authorization, +}; mod common; pub use common::TransactionInfo; @@ -103,7 +107,10 @@ pub struct Transaction { )] #[doc(alias = "tx_type")] pub transaction_type: Option, - + /// The signed authorization list is a list of tuples that store the address to code which the + /// signer desires to execute in the context of their EOA and their signature. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub authorization_list: Option>, /// Arbitrary extra fields. /// /// This captures fields that are not native to ethereum but included in ethereum adjacent networks, for example fields the [optimism `eth_getTransactionByHash` request](https://docs.alchemy.com/alchemy/apis/optimism/eth-gettransactionbyhash) returns additional fields that this type will capture @@ -272,8 +279,10 @@ impl TryFrom for TxEnvelope { #[cfg(test)] mod tests { use super::*; + use alloy_primitives::Signature as AlloySignature; use arbitrary::Arbitrary; use rand::Rng; + use std::str::FromStr; #[test] fn arbitrary_transaction() { @@ -310,12 +319,18 @@ mod tests { max_fee_per_gas: Some(21), max_priority_fee_per_gas: Some(22), max_fee_per_blob_gas: None, + authorization_list: Some(vec![(Authorization { + chain_id: 1u64, + address: Address::left_padding_from(&[6]), + nonce: Some(1u64).into(), + }) + .into_signed(AlloySignature::from_str("48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c8041b").unwrap())]), other: Default::default(), }; let serialized = serde_json::to_string(&transaction).unwrap(); assert_eq!( serialized, - r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000001","nonce":"0x2","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000003","blockNumber":"0x4","transactionIndex":"0x5","from":"0x0000000000000000000000000000000000000006","to":"0x0000000000000000000000000000000000000007","value":"0x8","gasPrice":"0x9","gas":"0xa","maxFeePerGas":"0x15","maxPriorityFeePerGas":"0x16","input":"0x0b0c0d","r":"0xe","s":"0xe","v":"0xe","chainId":"0x11","type":"0x14"}"# + r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000001","nonce":"0x2","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000003","blockNumber":"0x4","transactionIndex":"0x5","from":"0x0000000000000000000000000000000000000006","to":"0x0000000000000000000000000000000000000007","value":"0x8","gasPrice":"0x9","gas":"0xa","maxFeePerGas":"0x15","maxPriorityFeePerGas":"0x16","input":"0x0b0c0d","r":"0xe","s":"0xe","v":"0xe","chainId":"0x11","type":"0x14","authorizationList":[{"chainId":1,"address":"0x0000000000000000000000000000000000000006","nonce":1,"r":"0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353","s":"0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","v":27}]}"# ); let deserialized: Transaction = serde_json::from_str(&serialized).unwrap(); assert_eq!(transaction, deserialized); @@ -348,12 +363,18 @@ mod tests { max_fee_per_gas: Some(21), max_priority_fee_per_gas: Some(22), max_fee_per_blob_gas: None, + authorization_list: Some(vec![(Authorization { + chain_id: 1u64, + address: Address::left_padding_from(&[6]), + nonce: Some(1u64).into(), + }) + .into_signed(AlloySignature::from_str("48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c8041b").unwrap())]), other: Default::default(), }; let serialized = serde_json::to_string(&transaction).unwrap(); assert_eq!( serialized, - r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000001","nonce":"0x2","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000003","blockNumber":"0x4","transactionIndex":"0x5","from":"0x0000000000000000000000000000000000000006","to":"0x0000000000000000000000000000000000000007","value":"0x8","gasPrice":"0x9","gas":"0xa","maxFeePerGas":"0x15","maxPriorityFeePerGas":"0x16","input":"0x0b0c0d","r":"0xe","s":"0xe","v":"0xe","yParity":"0x1","chainId":"0x11","type":"0x14"}"# + r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000001","nonce":"0x2","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000003","blockNumber":"0x4","transactionIndex":"0x5","from":"0x0000000000000000000000000000000000000006","to":"0x0000000000000000000000000000000000000007","value":"0x8","gasPrice":"0x9","gas":"0xa","maxFeePerGas":"0x15","maxPriorityFeePerGas":"0x16","input":"0x0b0c0d","r":"0xe","s":"0xe","v":"0xe","yParity":"0x1","chainId":"0x11","type":"0x14","authorizationList":[{"chainId":1,"address":"0x0000000000000000000000000000000000000006","nonce":1,"r":"0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353","s":"0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","v":27}]}"# ); let deserialized: Transaction = serde_json::from_str(&serialized).unwrap(); assert_eq!(transaction, deserialized); diff --git a/crates/rpc-types-eth/src/transaction/receipt.rs b/crates/rpc-types-eth/src/transaction/receipt.rs index afc93c753b6..8d49e1488dc 100644 --- a/crates/rpc-types-eth/src/transaction/receipt.rs +++ b/crates/rpc-types-eth/src/transaction/receipt.rs @@ -1,5 +1,6 @@ use crate::Log; use alloy_consensus::{AnyReceiptEnvelope, ReceiptEnvelope, TxType}; +use alloy_eips::eip7702::SignedAuthorization; use alloy_primitives::{Address, BlockHash, TxHash, B256}; use alloy_serde::WithOtherFields; use serde::{Deserialize, Serialize}; @@ -56,6 +57,10 @@ pub struct TransactionReceipt> { /// EIP98 makes this optional field, if it's missing then skip serializing it #[serde(skip_serializing_if = "Option::is_none", rename = "root")] pub state_root: Option, + /// The authorization list is a list of tuples that store the address to code which the signer + /// desires to execute in the context of their EOA. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub authorization_list: Option>, } impl AsRef> for TransactionReceipt { @@ -114,6 +119,7 @@ impl TransactionReceipt { to: self.to, contract_address: self.contract_address, state_root: self.state_root, + authorization_list: self.authorization_list, } } } From ecea267c4a0bad3e1e0eddef3279bd9b0ae51e2b Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Mon, 15 Jul 2024 12:23:02 +0100 Subject: [PATCH 021/186] feat(rpc-types-eth): serde flatten `BlobTransactionSidecar` in tx req (#1054) --- .../rpc-types-eth/src/transaction/request.rs | 55 ++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/crates/rpc-types-eth/src/transaction/request.rs b/crates/rpc-types-eth/src/transaction/request.rs index ed27bae7ea4..a1fdd2c50e4 100644 --- a/crates/rpc-types-eth/src/transaction/request.rs +++ b/crates/rpc-types-eth/src/transaction/request.rs @@ -63,7 +63,7 @@ pub struct TransactionRequest { #[serde(default, skip_serializing_if = "Option::is_none")] pub blob_versioned_hashes: Option>, /// Blob sidecar for EIP-4844 transactions. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[serde(default, flatten, skip_serializing_if = "Option::is_none")] pub sidecar: Option, } @@ -847,4 +847,57 @@ mod tests { let serialized = serde_json::to_string(&tx).unwrap(); assert_eq!(serialized, "{}"); } + + #[test] + fn serde_tx_with_sidecar() { + // Create a sidecar with some data. + let s = r#"{ + "to": "0x70997970c51812dc3a010c7d01b50e0d17dc79c8", + "maxFeePerGas": "0x77359401", + "maxPriorityFeePerGas": "0x1", + "maxFeePerBlobGas": "0x77359400", + "nonce": "0x0", + "blobVersionedHashes": [ + "0x01b0761f87b081d5cf10757ccc89f12be355c70e2e29df288b65b30710dcbcd1" + ], + "blobs": [ + "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ], + "commitments": [ + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ], + "proofs": [ + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ] + } + "#; + + let req = serde_json::from_str::(s).unwrap(); + + assert!(req.sidecar.is_some()); + + let _serialized = serde_json::to_string_pretty(&req).unwrap(); + + let s = r#"{ + "to": "0x70997970c51812dc3a010c7d01b50e0d17dc79c8", + "maxFeePerGas": "0x77359401", + "maxPriorityFeePerGas": "0x1", + "maxFeePerBlobGas": "0x77359400", + "nonce": "0x0", + "blobVersionedHashes": [ + "0x01b0761f87b081d5cf10757ccc89f12be355c70e2e29df288b65b30710dcbcd1" + ], + "blobs": [ + "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ], + "commitments": [ + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + ] + } + "#; // `proofs` field is missing. + + let req = serde_json::from_str::(s).unwrap(); + + assert!(req.sidecar.is_none()); // Sidecar won't be deserialized. + } } From faee716c83a0252bcae0948dca3a208e8c449cdf Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Mon, 15 Jul 2024 14:46:56 +0200 Subject: [PATCH 022/186] feat: add 7702 tx type (#1046) --- crates/consensus/src/constants.rs | 3 + crates/consensus/src/transaction/eip7702.rs | 446 ++++++++++++++++++++ crates/consensus/src/transaction/mod.rs | 3 + 3 files changed, 452 insertions(+) create mode 100644 crates/consensus/src/transaction/eip7702.rs diff --git a/crates/consensus/src/constants.rs b/crates/consensus/src/constants.rs index 79987a18de9..c7a7090d098 100644 --- a/crates/consensus/src/constants.rs +++ b/crates/consensus/src/constants.rs @@ -80,3 +80,6 @@ pub const EIP1559_TX_TYPE_ID: u8 = 2; /// Identifier for an EIP4844 transaction. pub const EIP4844_TX_TYPE_ID: u8 = 3; + +/// Identifier for an EIP7702 transaction. +pub const EIP7702_TX_TYPE_ID: u8 = 4; diff --git a/crates/consensus/src/transaction/eip7702.rs b/crates/consensus/src/transaction/eip7702.rs new file mode 100644 index 00000000000..e8934d474d3 --- /dev/null +++ b/crates/consensus/src/transaction/eip7702.rs @@ -0,0 +1,446 @@ +use crate::{SignableTransaction, Signed, Transaction, TxType}; +use alloy_eips::eip2930::AccessList; +use alloy_primitives::{keccak256, Bytes, ChainId, Signature, TxKind, U256}; +use alloy_rlp::{BufMut, Decodable, Encodable, Header}; +use core::mem; + +#[cfg(not(feature = "std"))] +use alloc::vec::Vec; +use alloy_eips::eip7702::{constants::EIP7702_TX_TYPE_ID, SignedAuthorization}; + +/// A transaction with a priority fee ([EIP-7702](https://eips.ethereum.org/EIPS/eip-7702)). +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] +#[doc(alias = "Eip7702Transaction", alias = "TransactionEip7702", alias = "Eip7702Tx")] +pub struct TxEip7702 { + /// EIP-155: Simple replay attack protection + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))] + pub chain_id: ChainId, + /// A scalar value equal to the number of transactions sent by the sender; formally Tn. + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))] + pub nonce: u64, + /// A scalar value equal to the maximum + /// amount of gas that should be used in executing + /// this transaction. This is paid up-front, before any + /// computation is done and may not be increased + /// later; formally Tg. + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))] + pub gas_limit: u128, + /// A scalar value equal to the maximum + /// amount of gas that should be used in executing + /// this transaction. This is paid up-front, before any + /// computation is done and may not be increased + /// later; formally Tg. + /// + /// As ethereum circulation is around 120mil eth as of 2022 that is around + /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: + /// 340282366920938463463374607431768211455 + /// + /// This is also known as `GasFeeCap` + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))] + pub max_fee_per_gas: u128, + /// Max Priority fee that transaction is paying + /// + /// As ethereum circulation is around 120mil eth as of 2022 that is around + /// 120000000000000000000000000 wei we are safe to use u128 as its max number is: + /// 340282366920938463463374607431768211455 + /// + /// This is also known as `GasTipCap` + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))] + pub max_priority_fee_per_gas: u128, + /// The 160-bit address of the message call’s recipient or, for a contract creation + /// transaction, ∅, used here to denote the only member of B0 ; formally Tt. + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "TxKind::is_create"))] + pub to: TxKind, + /// A scalar value equal to the number of Wei to + /// be transferred to the message call’s recipient or, + /// in the case of contract creation, as an endowment + /// to the newly created account; formally Tv. + pub value: U256, + /// The accessList specifies a list of addresses and storage keys; + /// these addresses and storage keys are added into the `accessed_addresses` + /// and `accessed_storage_keys` global sets (introduced in EIP-2929). + /// A gas cost is charged, though at a discount relative to the cost of + /// accessing outside the list. + pub access_list: AccessList, + /// Authorizations are used to temporarily set the code of its signer to + /// the code referenced by `address`. These also include a `chain_id` (which + /// can be set to zero and not evaluated) as well as an optional `nonce`. + pub authorization_list: Vec, + /// Input has two uses depending if transaction is Create or Call (if `to` field is None or + /// Some). pub init: An unlimited size byte array specifying the + /// EVM-code for the account initialisation procedure CREATE, + /// data: An unlimited size byte array specifying the + /// input data of the message call, formally Td. + pub input: Bytes, +} + +impl TxEip7702 { + /// Returns the effective gas price for the given `base_fee`. + pub const fn effective_gas_price(&self, base_fee: Option) -> u128 { + match base_fee { + None => self.max_fee_per_gas, + Some(base_fee) => { + // if the tip is greater than the max priority fee per gas, set it to the max + // priority fee per gas + base fee + let tip = self.max_fee_per_gas.saturating_sub(base_fee as u128); + if tip > self.max_priority_fee_per_gas { + self.max_priority_fee_per_gas + base_fee as u128 + } else { + // otherwise return the max fee per gas + self.max_fee_per_gas + } + } + } + } + + /// Decodes the inner [TxEip7702] fields from RLP bytes. + /// + /// NOTE: This assumes a RLP header has already been decoded, and _just_ decodes the following + /// RLP fields in the following order: + /// + /// - `chain_id` + /// - `nonce` + /// - `max_priority_fee_per_gas` + /// - `max_fee_per_gas` + /// - `gas_limit` + /// - `to` + /// - `value` + /// - `data` (`input`) + /// - `access_list` + /// - `authorization_list` + pub(crate) fn decode_fields(buf: &mut &[u8]) -> alloy_rlp::Result { + Ok(Self { + chain_id: Decodable::decode(buf)?, + nonce: Decodable::decode(buf)?, + max_priority_fee_per_gas: Decodable::decode(buf)?, + max_fee_per_gas: Decodable::decode(buf)?, + gas_limit: Decodable::decode(buf)?, + to: Decodable::decode(buf)?, + value: Decodable::decode(buf)?, + input: Decodable::decode(buf)?, + access_list: Decodable::decode(buf)?, + authorization_list: Decodable::decode(buf)?, + }) + } + + /// Outputs the length of the transaction's fields, without a RLP header. + #[doc(hidden)] + pub fn fields_len(&self) -> usize { + let mut len = 0; + len += self.chain_id.length(); + len += self.nonce.length(); + len += self.max_priority_fee_per_gas.length(); + len += self.max_fee_per_gas.length(); + len += self.gas_limit.length(); + len += self.to.length(); + len += self.value.length(); + len += self.input.0.length(); + len += self.access_list.length(); + len += self.authorization_list.length(); + len + } + + /// Encodes only the transaction's fields into the desired buffer, without a RLP header. + pub(crate) fn encode_fields(&self, out: &mut dyn alloy_rlp::BufMut) { + self.chain_id.encode(out); + self.nonce.encode(out); + self.max_priority_fee_per_gas.encode(out); + self.max_fee_per_gas.encode(out); + self.gas_limit.encode(out); + self.to.encode(out); + self.value.encode(out); + self.input.0.encode(out); + self.access_list.encode(out); + self.authorization_list.encode(out); + } + + /// Returns what the encoded length should be, if the transaction were RLP encoded with the + /// given signature, depending on the value of `with_header`. + /// + /// If `with_header` is `true`, the payload length will include the RLP header length. + /// If `with_header` is `false`, the payload length will not include the RLP header length. + pub(crate) fn encoded_len_with_signature( + &self, + signature: &Signature, + with_header: bool, + ) -> usize { + // this counts the tx fields and signature fields + let payload_length = self.fields_len() + signature.rlp_vrs_len(); + + // this counts: + // * tx type byte + // * inner header length + // * inner payload length + let inner_payload_length = + 1 + Header { list: true, payload_length }.length() + payload_length; + + if with_header { + // header length plus length of the above, wrapped with a string header + Header { list: false, payload_length: inner_payload_length }.length() + + inner_payload_length + } else { + inner_payload_length + } + } + + /// Inner encoding function that is used for both rlp [`Encodable`] trait and for calculating + /// hash that for eip2718 does not require a rlp header. + #[doc(hidden)] + pub fn encode_with_signature( + &self, + signature: &Signature, + out: &mut dyn BufMut, + with_header: bool, + ) { + let payload_length = self.fields_len() + signature.rlp_vrs_len(); + if with_header { + Header { + list: false, + payload_length: 1 + Header { list: true, payload_length }.length() + payload_length, + } + .encode(out); + } + out.put_u8(EIP7702_TX_TYPE_ID); + self.encode_with_signature_fields(signature, out); + } + + /// Decodes the transaction from RLP bytes, including the signature. + /// + /// This __does not__ expect the bytes to start with a transaction type byte or string + /// header. + /// + /// This __does__ expect the bytes to start with a list header and include a signature. + #[doc(hidden)] + pub fn decode_signed_fields(buf: &mut &[u8]) -> alloy_rlp::Result> { + let header = Header::decode(buf)?; + if !header.list { + return Err(alloy_rlp::Error::UnexpectedString); + } + + // record original length so we can check encoding + let original_len = buf.len(); + + let tx = Self::decode_fields(buf)?; + let signature = Signature::decode_rlp_vrs(buf)?; + + let signed = tx.into_signed(signature); + if buf.len() + header.payload_length != original_len { + return Err(alloy_rlp::Error::ListLengthMismatch { + expected: header.payload_length, + got: original_len - buf.len(), + }); + } + + Ok(signed) + } + + /// Encodes the transaction from RLP bytes, including the signature. This __does not__ encode a + /// tx type byte or string header. + /// + /// This __does__ encode a list header and include a signature. + pub(crate) fn encode_with_signature_fields(&self, signature: &Signature, out: &mut dyn BufMut) { + let payload_length = self.fields_len() + signature.rlp_vrs_len(); + let header = Header { list: true, payload_length }; + header.encode(out); + self.encode_fields(out); + signature.write_rlp_vrs(out); + } + + /// Get transaction type + #[doc(alias = "transaction_type")] + #[allow(unused)] + pub(crate) fn tx_type(&self) -> TxType { + unimplemented!("not yet added to tx type enum") + } + + /// Calculates a heuristic for the in-memory size of the [TxEip7702] transaction. + #[inline] + pub fn size(&self) -> usize { + mem::size_of::() + // chain_id + mem::size_of::() + // nonce + mem::size_of::() + // gas_limit + mem::size_of::() + // max_fee_per_gas + mem::size_of::() + // max_priority_fee_per_gas + self.to.size() + // to + mem::size_of::() + // value + self.access_list.size() + // access_list + self.input.len() + // input + self.authorization_list.capacity() * mem::size_of::() // authorization_list + } +} + +impl Transaction for TxEip7702 { + fn chain_id(&self) -> Option { + Some(self.chain_id) + } + + fn nonce(&self) -> u64 { + self.nonce + } + + fn gas_limit(&self) -> u128 { + self.gas_limit + } + + fn gas_price(&self) -> Option { + None + } + + fn to(&self) -> TxKind { + self.to + } + + fn value(&self) -> U256 { + self.value + } + + fn input(&self) -> &[u8] { + &self.input + } +} + +impl SignableTransaction for TxEip7702 { + fn set_chain_id(&mut self, chain_id: ChainId) { + self.chain_id = chain_id; + } + + fn encode_for_signing(&self, out: &mut dyn alloy_rlp::BufMut) { + out.put_u8(EIP7702_TX_TYPE_ID); + self.encode(out) + } + + fn payload_len_for_signature(&self) -> usize { + self.length() + 1 + } + + fn into_signed(self, signature: Signature) -> Signed { + // Drop any v chain id value to ensure the signature format is correct at the time of + // combination for an EIP-7702 transaction. V should indicate the y-parity of the + // signature. + let signature = signature.with_parity_bool(); + + let mut buf = Vec::with_capacity(self.encoded_len_with_signature(&signature, false)); + self.encode_with_signature(&signature, &mut buf, false); + let hash = keccak256(&buf); + + Signed::new_unchecked(self, signature, hash) + } +} + +impl Encodable for TxEip7702 { + fn encode(&self, out: &mut dyn BufMut) { + Header { list: true, payload_length: self.fields_len() }.encode(out); + self.encode_fields(out); + } + + fn length(&self) -> usize { + let payload_length = self.fields_len(); + Header { list: true, payload_length }.length() + payload_length + } +} + +impl Decodable for TxEip7702 { + fn decode(data: &mut &[u8]) -> alloy_rlp::Result { + let header = Header::decode(data)?; + let remaining_len = data.len(); + + if header.payload_length > remaining_len { + return Err(alloy_rlp::Error::InputTooShort); + } + + Self::decode_fields(data) + } +} + +#[cfg(all(test, feature = "k256"))] +mod tests { + use super::TxEip7702; + use crate::SignableTransaction; + use alloy_eips::eip2930::AccessList; + use alloy_primitives::{address, b256, hex, Address, Signature, TxKind, U256}; + + #[test] + fn encode_decode_eip7702() { + let tx = TxEip7702 { + chain_id: 1, + nonce: 0x42, + gas_limit: 44386, + to: address!("6069a6c32cf691f5982febae4faf8a6f3ab2f0f6").into(), + value: U256::from(0_u64), + input: hex!("a22cb4650000000000000000000000005eee75727d804a2b13038928d36f8b188945a57a0000000000000000000000000000000000000000000000000000000000000000").into(), + max_fee_per_gas: 0x4a817c800, + max_priority_fee_per_gas: 0x3b9aca00, + access_list: AccessList::default(), + authorization_list: vec![], + }; + + let sig = Signature::from_scalars_and_parity( + b256!("840cfc572845f5786e702984c2a582528cad4b49b2a10b9db1be7fca90058565"), + b256!("25e7109ceb98168d95b09b18bbf6b685130e0562f233877d492b94eee0c5b6d1"), + false, + ) + .unwrap(); + + let mut buf = vec![]; + tx.encode_with_signature_fields(&sig, &mut buf); + let decoded = TxEip7702::decode_signed_fields(&mut &buf[..]).unwrap(); + assert_eq!(decoded, tx.into_signed(sig)); + } + + #[test] + fn test_decode_create() { + // tests that a contract creation tx encodes and decodes properly + let tx = TxEip7702 { + chain_id: 1u64, + nonce: 0, + max_fee_per_gas: 0x4a817c800, + max_priority_fee_per_gas: 0x3b9aca00, + gas_limit: 2, + to: TxKind::Create, + value: U256::ZERO, + input: vec![1, 2].into(), + access_list: Default::default(), + authorization_list: Default::default(), + }; + let sig = Signature::from_scalars_and_parity( + b256!("840cfc572845f5786e702984c2a582528cad4b49b2a10b9db1be7fca90058565"), + b256!("25e7109ceb98168d95b09b18bbf6b685130e0562f233877d492b94eee0c5b6d1"), + false, + ) + .unwrap(); + let mut buf = vec![]; + tx.encode_with_signature_fields(&sig, &mut buf); + let decoded = TxEip7702::decode_signed_fields(&mut &buf[..]).unwrap(); + assert_eq!(decoded, tx.into_signed(sig)); + } + + #[test] + fn test_decode_call() { + let tx = TxEip7702 { + chain_id: 1u64, + nonce: 0, + max_fee_per_gas: 0x4a817c800, + max_priority_fee_per_gas: 0x3b9aca00, + gas_limit: 2, + to: Address::default().into(), + value: U256::ZERO, + input: vec![1, 2].into(), + access_list: Default::default(), + authorization_list: Default::default(), + }; + + let sig = Signature::from_scalars_and_parity( + b256!("840cfc572845f5786e702984c2a582528cad4b49b2a10b9db1be7fca90058565"), + b256!("25e7109ceb98168d95b09b18bbf6b685130e0562f233877d492b94eee0c5b6d1"), + false, + ) + .unwrap(); + + let mut buf = vec![]; + tx.encode_with_signature_fields(&sig, &mut buf); + let decoded = TxEip7702::decode_signed_fields(&mut &buf[..]).unwrap(); + assert_eq!(decoded, tx.into_signed(sig)); + } +} diff --git a/crates/consensus/src/transaction/mod.rs b/crates/consensus/src/transaction/mod.rs index ab8237346a7..0b2307c4122 100644 --- a/crates/consensus/src/transaction/mod.rs +++ b/crates/consensus/src/transaction/mod.rs @@ -13,6 +13,9 @@ pub use eip1559::TxEip1559; mod eip2930; pub use eip2930::TxEip2930; +mod eip7702; +pub use eip7702::TxEip7702; + /// [EIP-4844] constants, helpers, and types. pub mod eip4844; From 008b99d51ed43437fd6cfae261e9d7b16134b94d Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Mon, 15 Jul 2024 13:58:25 +0100 Subject: [PATCH 023/186] refactor: replace `U64` with `u64` (#1057) * refactor: replace `U64` with `u64` in rpc-types-(eth|trace) * replace `U64` in rpc-types-(eth|engine) * use u128 in OptimismTransactionFields.mint --- crates/rpc-types-engine/src/transition.rs | 5 +-- crates/rpc-types-eth/src/account.rs | 6 ++-- crates/rpc-types-eth/src/block.rs | 15 ++++++--- crates/rpc-types-eth/src/call.rs | 2 +- crates/rpc-types-eth/src/state.rs | 8 ++--- .../rpc-types-eth/src/transaction/optimism.rs | 19 +++++++----- crates/rpc-types-trace/src/parity.rs | 31 +++++++++++-------- 7 files changed, 51 insertions(+), 35 deletions(-) diff --git a/crates/rpc-types-engine/src/transition.rs b/crates/rpc-types-engine/src/transition.rs index 070ab9243a9..a63cdf3f596 100644 --- a/crates/rpc-types-engine/src/transition.rs +++ b/crates/rpc-types-engine/src/transition.rs @@ -1,4 +1,4 @@ -use alloy_primitives::{B256, U256, U64}; +use alloy_primitives::{B256, U256}; use serde::{Deserialize, Serialize}; /// This structure contains configurable settings of the transition process. @@ -11,5 +11,6 @@ pub struct TransitionConfiguration { /// Maps on TERMINAL_BLOCK_HASH parameter of EIP-3675 pub terminal_block_hash: B256, /// Maps on TERMINAL_BLOCK_NUMBER parameter of EIP-3675 - pub terminal_block_number: U64, + #[serde(with = "alloy_serde::quantity")] + pub terminal_block_number: u64, } diff --git a/crates/rpc-types-eth/src/account.rs b/crates/rpc-types-eth/src/account.rs index 26f6c9497ea..10d6e9e3b16 100644 --- a/crates/rpc-types-eth/src/account.rs +++ b/crates/rpc-types-eth/src/account.rs @@ -1,7 +1,6 @@ -use alloy_primitives::{Address, Bytes, B256, B512, U256, U64}; +use alloy_primitives::{Address, Bytes, B256, B512, U256}; use alloy_serde::storage::JsonStorageKey; use serde::{Deserialize, Serialize}; - /// Account information. #[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] pub struct AccountInfo { @@ -32,7 +31,8 @@ pub struct EIP1186AccountProofResponse { /// The hash of the code of the account. pub code_hash: B256, /// The account nonce. - pub nonce: U64, + #[serde(with = "alloy_serde::quantity")] + pub nonce: u64, /// The hash of the storage of the account. pub storage_hash: B256, /// The account proof. diff --git a/crates/rpc-types-eth/src/block.rs b/crates/rpc-types-eth/src/block.rs index c2ff60ade05..3a549f55c82 100644 --- a/crates/rpc-types-eth/src/block.rs +++ b/crates/rpc-types-eth/src/block.rs @@ -1,7 +1,7 @@ //! Block RPC types. use crate::{ConversionError, Transaction, Withdrawal}; -use alloy_primitives::{Address, BlockHash, Bloom, Bytes, B256, B64, U256, U64}; +use alloy_primitives::{Address, BlockHash, Bloom, Bytes, B256, B64, U256}; use alloy_serde::OtherFields; use serde::{ser::Error, Deserialize, Serialize, Serializer}; use std::{collections::BTreeMap, ops::Deref}; @@ -608,11 +608,16 @@ pub struct BlockOverrides { pub difficulty: Option, /// Overrides the timestamp of the block. // Note: geth uses `time`, erigon uses `timestamp` - #[serde(default, skip_serializing_if = "Option::is_none", alias = "timestamp")] - pub time: Option, + #[serde( + default, + skip_serializing_if = "Option::is_none", + alias = "timestamp", + with = "alloy_serde::quantity::opt" + )] + pub time: Option, /// Overrides the gas limit of the block. - #[serde(default, skip_serializing_if = "Option::is_none")] - pub gas_limit: Option, + #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] + pub gas_limit: Option, /// Overrides the coinbase address of the block. #[serde(default, skip_serializing_if = "Option::is_none")] pub coinbase: Option
, diff --git a/crates/rpc-types-eth/src/call.rs b/crates/rpc-types-eth/src/call.rs index 934b637e1eb..09f47660e5b 100644 --- a/crates/rpc-types-eth/src/call.rs +++ b/crates/rpc-types-eth/src/call.rs @@ -145,7 +145,7 @@ mod tests { let s = r#"{"transactions":[{"data":"0x70a08231000000000000000000000000000000dbc80bf780c6dc0ca16ed071b1f00cc000","to":"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"}],"blockOverride":{"timestamp":1711546233}}"#; let bundle = serde_json::from_str::(s).unwrap(); assert_eq!(bundle.transactions.len(), 1); - assert_eq!(bundle.block_override.unwrap().time.unwrap().to::(), 1711546233); + assert_eq!(bundle.block_override.unwrap().time.unwrap(), 1711546233); } #[test] diff --git a/crates/rpc-types-eth/src/state.rs b/crates/rpc-types-eth/src/state.rs index 89a7fbf7671..4746e5368da 100644 --- a/crates/rpc-types-eth/src/state.rs +++ b/crates/rpc-types-eth/src/state.rs @@ -1,7 +1,7 @@ //! bindings for state overrides in eth_call use crate::BlockOverrides; -use alloy_primitives::{Address, Bytes, B256, U256, U64}; +use alloy_primitives::{Address, Bytes, B256, U256}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -16,8 +16,8 @@ pub struct AccountOverride { #[serde(default, skip_serializing_if = "Option::is_none")] pub balance: Option, /// Fake nonce to set for the account before executing the call. - #[serde(default, skip_serializing_if = "Option::is_none")] - pub nonce: Option, + #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] + pub nonce: Option, /// Fake EVM bytecode to inject into the account before executing the call. #[serde(default, skip_serializing_if = "Option::is_none")] pub code: Option, @@ -113,7 +113,7 @@ mod tests { let acc = state_override.get(&address!("1234567890123456789012345678901234567890")).unwrap(); assert_eq!(acc.balance, Some(U256::MAX)); - assert_eq!(acc.nonce, Some(U64::MAX)); + assert_eq!(acc.nonce, Some(u64::MAX)); } #[test] diff --git a/crates/rpc-types-eth/src/transaction/optimism.rs b/crates/rpc-types-eth/src/transaction/optimism.rs index eac57944fdd..835806ce414 100644 --- a/crates/rpc-types-eth/src/transaction/optimism.rs +++ b/crates/rpc-types-eth/src/transaction/optimism.rs @@ -1,6 +1,6 @@ //! Misc Optimism-specific types. -use alloy_primitives::{B256, U128, U64}; +use alloy_primitives::B256; use alloy_serde::OtherFields; use serde::{Deserialize, Serialize}; @@ -12,8 +12,13 @@ pub struct OptimismTransactionFields { #[serde(rename = "sourceHash", skip_serializing_if = "Option::is_none")] pub source_hash: Option, /// The ETH value to mint on L2 - #[serde(rename = "mint", skip_serializing_if = "Option::is_none")] - pub mint: Option, + #[serde( + default, + rename = "mint", + skip_serializing_if = "Option::is_none", + with = "alloy_serde::quantity::opt" + )] + pub mint: Option, /// Field indicating whether the transaction is a system transaction, and therefore /// exempt from the L2 gas limit. #[serde(rename = "isSystemTx", skip_serializing_if = "Option::is_none")] @@ -27,11 +32,11 @@ pub struct OptimismTransactionFields { #[doc(alias = "OptimismTxReceiptFields")] pub struct OptimismTransactionReceiptFields { /// Deposit nonce for deposit transactions post-regolith - #[serde(skip_serializing_if = "Option::is_none")] - pub deposit_nonce: Option, + #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] + pub deposit_nonce: Option, /// Deposit receipt version for deposit transactions post-canyon - #[serde(skip_serializing_if = "Option::is_none")] - pub deposit_receipt_version: Option, + #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] + pub deposit_receipt_version: Option, /// L1 fee for the transaction #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] pub l1_fee: Option, diff --git a/crates/rpc-types-trace/src/parity.rs b/crates/rpc-types-trace/src/parity.rs index e3c1ef4d539..21abea91bb2 100644 --- a/crates/rpc-types-trace/src/parity.rs +++ b/crates/rpc-types-trace/src/parity.rs @@ -133,6 +133,7 @@ pub struct AccountDiff { /// How the code changed, if at all pub code: Delta, /// How the nonce changed, if at all + // TODO: Change type to `u64` and write custom serde for `Delta` pub nonce: Delta, /// All touched/changed storage values pub storage: BTreeMap>, @@ -288,7 +289,8 @@ pub struct CallAction { /// The type of the call. pub call_type: CallType, /// The gas available for executing the call. - pub gas: U64, + #[serde(with = "alloy_serde::quantity")] + pub gas: u64, /// The input data provided to the call. pub input: Bytes, /// Address of the destination/target account. @@ -304,7 +306,8 @@ pub struct CreateAction { /// The address of the creator. pub from: Address, /// The gas available for the creation init code. - pub gas: U64, + #[serde(with = "alloy_serde::quantity")] + pub gas: u64, /// The init code. pub init: Bytes, /// The value with which the new account is endowed. @@ -350,7 +353,8 @@ pub struct SelfdestructAction { #[serde(rename_all = "camelCase")] pub struct CallOutput { /// Gas used by the call. - pub gas_used: U64, + #[serde(with = "alloy_serde::quantity")] + pub gas_used: u64, /// The output data of the call. pub output: Bytes, } @@ -364,7 +368,8 @@ pub struct CreateOutput { /// Contract code. pub code: Bytes, /// Gas used by the call. - pub gas_used: U64, + #[serde(with = "alloy_serde::quantity")] + pub gas_used: u64, } /// Represents the output of a trace. @@ -395,18 +400,18 @@ impl TraceOutput { } /// Returns the gas used by this trace. - pub fn gas_used(&self) -> u64 { + pub const fn gas_used(&self) -> u64 { match self { - Self::Call(call) => call.gas_used.to(), - Self::Create(create) => create.gas_used.to(), + Self::Call(call) => call.gas_used, + Self::Create(create) => create.gas_used, } } /// Sets the gas used by this trace. pub fn set_gas_used(&mut self, gas_used: u64) { match self { - Self::Call(call) => call.gas_used = U64::from(gas_used), - Self::Create(create) => create.gas_used = U64::from(gas_used), + Self::Call(call) => call.gas_used = gas_used, + Self::Create(create) => create.gas_used = gas_used, } } } @@ -660,13 +665,13 @@ mod tests { action: Action::Call(CallAction { from: "0x4f4495243837681061c4743b74b3eedf548d56a5".parse::
().unwrap(), call_type: CallType::DelegateCall, - gas: U64::from(3148955), + gas: 3148955, input: Bytes::from_str("0x585a9fd40000000000000000000000000000000000000000000000000000000000000040a47c5ad9a4af285720eae6cc174a9c75c5bbaf973b00f1a0c191327445b6581000000000000000000000000000000000000000000000000000000000000001e000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000ce16f69375520ab01377ce7b88f5ba8c48f8d666f61490331372e432315cd97447e3bc452d6c73a6e0536260a88ddab46f85c88d00000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000aab8cf0fbfb038751339cb61161fa11789b41a78f1b7b0e12cf8e467d403590b7a5f26f0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000646616e746f6d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002a3078636531364636393337353532306162303133373763653742383866354241384334384638443636360000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000045553444300000000000000000000000000000000000000000000000000000000").unwrap(), to: "0x99b5fa03a5ea4315725c43346e55a6a6fbd94098".parse::
().unwrap(), value: U256::from(0), }), error: None, - result: Some(TraceOutput::Call(CallOutput { gas_used: U64::from(32364), output: Bytes::new() })), + result: Some(TraceOutput::Call(CallOutput { gas_used: 32364, output: Bytes::new() })), subtraces: 0, trace_address: vec![0, 10, 0], }, @@ -706,12 +711,12 @@ mod tests { trace: TransactionTrace { action: Action::Create(CreateAction{ from: "0x4f4495243837681061c4743b74b3eedf548d56a5".parse::
().unwrap(), - gas: U64::from(3438907), + gas: 3438907, init: Bytes::from_str("0x6080604052600160005534801561001557600080fd5b50610324806100256000396000f3fe608060405234801561001057600080fd5b50600436106100355760003560e01c8062f55d9d1461003a5780631cff79cd1461004f575b600080fd5b61004d6100483660046101da565b610079565b005b61006261005d3660046101fc565b6100bb565b60405161007092919061027f565b60405180910390f35b6002600054141561009d5760405163caa30f5560e01b815260040160405180910390fd5b600260005573ffffffffffffffffffffffffffffffffffffffff8116ff5b60006060600260005414156100e35760405163caa30f5560e01b815260040160405180910390fd5b600260005573ffffffffffffffffffffffffffffffffffffffff85163b610136576040517f6f7c43f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff16848460405161015d9291906102de565b6000604051808303816000865af19150503d806000811461019a576040519150601f19603f3d011682016040523d82523d6000602084013e61019f565b606091505b50600160005590969095509350505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101d557600080fd5b919050565b6000602082840312156101ec57600080fd5b6101f5826101b1565b9392505050565b60008060006040848603121561021157600080fd5b61021a846101b1565b9250602084013567ffffffffffffffff8082111561023757600080fd5b818601915086601f83011261024b57600080fd5b81358181111561025a57600080fd5b87602082850101111561026c57600080fd5b6020830194508093505050509250925092565b821515815260006020604081840152835180604085015260005b818110156102b557858101830151858201606001528201610299565b818111156102c7576000606083870101525b50601f01601f191692909201606001949350505050565b818382376000910190815291905056fea264697066735822122032cb5e746816b7fac95205c068b30da37bd40119a57265be331c162cae74712464736f6c63430008090033").unwrap(), value: U256::from(0), }), error: None, - result: Some(TraceOutput::Create(CreateOutput { gas_used: U64::from(183114), address: "0x7eb6c6c1db08c0b9459a68cfdcedab64f319c138".parse::
().unwrap(), code: Bytes::from_str("0x608060405234801561001057600080fd5b50600436106100355760003560e01c8062f55d9d1461003a5780631cff79cd1461004f575b600080fd5b61004d6100483660046101da565b610079565b005b61006261005d3660046101fc565b6100bb565b60405161007092919061027f565b60405180910390f35b6002600054141561009d5760405163caa30f5560e01b815260040160405180910390fd5b600260005573ffffffffffffffffffffffffffffffffffffffff8116ff5b60006060600260005414156100e35760405163caa30f5560e01b815260040160405180910390fd5b600260005573ffffffffffffffffffffffffffffffffffffffff85163b610136576040517f6f7c43f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff16848460405161015d9291906102de565b6000604051808303816000865af19150503d806000811461019a576040519150601f19603f3d011682016040523d82523d6000602084013e61019f565b606091505b50600160005590969095509350505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101d557600080fd5b919050565b6000602082840312156101ec57600080fd5b6101f5826101b1565b9392505050565b60008060006040848603121561021157600080fd5b61021a846101b1565b9250602084013567ffffffffffffffff8082111561023757600080fd5b818601915086601f83011261024b57600080fd5b81358181111561025a57600080fd5b87602082850101111561026c57600080fd5b6020830194508093505050509250925092565b821515815260006020604081840152835180604085015260005b818110156102b557858101830151858201606001528201610299565b818111156102c7576000606083870101525b50601f01601f191692909201606001949350505050565b818382376000910190815291905056fea264697066735822122032cb5e746816b7fac95205c068b30da37bd40119a57265be331c162cae74712464736f6c63430008090033").unwrap() })), + result: Some(TraceOutput::Create(CreateOutput { gas_used: 183114, address: "0x7eb6c6c1db08c0b9459a68cfdcedab64f319c138".parse::
().unwrap(), code: Bytes::from_str("0x608060405234801561001057600080fd5b50600436106100355760003560e01c8062f55d9d1461003a5780631cff79cd1461004f575b600080fd5b61004d6100483660046101da565b610079565b005b61006261005d3660046101fc565b6100bb565b60405161007092919061027f565b60405180910390f35b6002600054141561009d5760405163caa30f5560e01b815260040160405180910390fd5b600260005573ffffffffffffffffffffffffffffffffffffffff8116ff5b60006060600260005414156100e35760405163caa30f5560e01b815260040160405180910390fd5b600260005573ffffffffffffffffffffffffffffffffffffffff85163b610136576040517f6f7c43f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff16848460405161015d9291906102de565b6000604051808303816000865af19150503d806000811461019a576040519150601f19603f3d011682016040523d82523d6000602084013e61019f565b606091505b50600160005590969095509350505050565b803573ffffffffffffffffffffffffffffffffffffffff811681146101d557600080fd5b919050565b6000602082840312156101ec57600080fd5b6101f5826101b1565b9392505050565b60008060006040848603121561021157600080fd5b61021a846101b1565b9250602084013567ffffffffffffffff8082111561023757600080fd5b818601915086601f83011261024b57600080fd5b81358181111561025a57600080fd5b87602082850101111561026c57600080fd5b6020830194508093505050509250925092565b821515815260006020604081840152835180604085015260005b818110156102b557858101830151858201606001528201610299565b818111156102c7576000606083870101525b50601f01601f191692909201606001949350505050565b818382376000910190815291905056fea264697066735822122032cb5e746816b7fac95205c068b30da37bd40119a57265be331c162cae74712464736f6c63430008090033").unwrap() })), subtraces: 0, trace_address: vec![0, 7, 0, 0], }, From 1d0c81dcdc522b77c392c92c0814f41413011af2 Mon Sep 17 00:00:00 2001 From: John Guibas Date: Tue, 16 Jul 2024 01:38:33 -0700 Subject: [PATCH 024/186] fix: require storageKeys value broken bincode serialization from #955 (#1058) * fix: broken bincode serialization from #955 * remove optional in alloy-serde * resolve matt's comments * get rid of broken test * fix cargo fmt * enforce storage key --------- Co-authored-by: Matthias Seitz --- crates/eips/src/eip2930.rs | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/crates/eips/src/eip2930.rs b/crates/eips/src/eip2930.rs index 094361fa152..2686d7bf8ec 100644 --- a/crates/eips/src/eip2930.rs +++ b/crates/eips/src/eip2930.rs @@ -8,7 +8,6 @@ use alloc::vec::Vec; use alloy_primitives::{Address, B256, U256}; use alloy_rlp::{RlpDecodable, RlpDecodableWrapper, RlpEncodable, RlpEncodableWrapper}; use core::{mem, ops::Deref}; - /// A list of addresses and storage keys that the transaction plans to access. /// Accesses outside the list are possible, but become more expensive. #[derive(Clone, Debug, Default, PartialEq, Eq, Hash, RlpDecodable, RlpEncodable)] @@ -19,8 +18,6 @@ pub struct AccessListItem { /// Account addresses that would be loaded at the start of execution pub address: Address, /// Keys of storage that would be loaded at the start of execution - // In JSON, we have to accept `null` for storage key, which is interpreted as an empty array. - #[cfg_attr(feature = "serde", serde(deserialize_with = "alloy_serde::null_as_default"))] pub storage_keys: Vec, } @@ -146,24 +143,8 @@ pub struct AccessListWithGasUsed { #[cfg(all(test, feature = "serde"))] mod tests { - use serde_json::json; - use super::*; - #[test] - fn access_list_null_storage_keys() { - let json = json!([ - { - "address": "0x81b7bdd5b89c90b63f604fc7cdd17035cb939707", - "storageKeys": null, - } - ]); - - let access_list = serde_json::from_value::(json).unwrap(); - assert_eq!(access_list.len(), 1); - assert_eq!(access_list[0].storage_keys, Vec::::default()); - } - #[test] fn access_list_serde() { let list = AccessList(vec![ From 0950b03a1f51df86bd3f2073715b98e13d3886f4 Mon Sep 17 00:00:00 2001 From: morito Date: Tue, 16 Jul 2024 19:27:56 +0900 Subject: [PATCH 025/186] fix(provider): Prevent panic from having 0 keys when calling `on_anvil_with_wallet_and_config` (#1055) * node-bindings: Add AnvilError::NoKeysAvailable * prevent panic from having 0 keys * fix the error handlings for `on_anvil_with_wallet` * fix clippy * fix(clippy): Add type alias * Add `try_on_anvil_with_wallet_and_config` and call it in `on_anvil_with_wallet_and_config` * Revert test changes * Fix docs --- crates/node-bindings/src/anvil.rs | 4 +++ crates/provider/src/builder.rs | 49 +++++++++++++++++++++++++------ 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/crates/node-bindings/src/anvil.rs b/crates/node-bindings/src/anvil.rs index 0928957203c..62903e9c2e7 100644 --- a/crates/node-bindings/src/anvil.rs +++ b/crates/node-bindings/src/anvil.rs @@ -119,6 +119,10 @@ pub enum AnvilError { /// An error occurred while parsing a hex string. #[error(transparent)] FromHexError(#[from] hex::FromHexError), + + /// No keys available in anvil instance. + #[error("no keys available in anvil instance")] + NoKeysAvailable, } /// Builder for launching `anvil`. diff --git a/crates/provider/src/builder.rs b/crates/provider/src/builder.rs index 5105351d75f..3871ac86865 100644 --- a/crates/provider/src/builder.rs +++ b/crates/provider/src/builder.rs @@ -10,7 +10,6 @@ use alloy_chains::NamedChain; use alloy_network::{Ethereum, Network}; use alloy_primitives::ChainId; use alloy_rpc_client::{BuiltInConnectionString, ClientBuilder, RpcClient}; - use alloy_transport::{BoxTransport, Transport, TransportError, TransportResult}; use std::marker::PhantomData; @@ -347,6 +346,11 @@ impl ProviderBuilder { } } +type JoinedEthereumWalletFiller = JoinFill>; + +#[cfg(any(test, feature = "anvil-node"))] +type AnvilProviderResult = Result; + // Enabled when the `anvil` feature is enabled, or when both in test and the // `reqwest` feature is enabled. #[cfg(any(test, feature = "anvil-node"))] @@ -372,7 +376,7 @@ impl ProviderBuilder { /// use in tests. pub fn on_anvil_with_wallet( self, - ) -> > as ProviderLayer< + ) -> as ProviderLayer< L::Provider, alloy_transport_http::Http, >>::Provider @@ -413,17 +417,42 @@ impl ProviderBuilder { self.layer(anvil_layer).on_http(url) } - /// Build this provider with anvil, using an Reqwest HTTP transport. The - /// given function is used to configure the anvil instance. This - /// function configures a wallet backed by anvil keys, and is intended for - /// use in tests. + /// Build this provider with anvil, using an Reqwest HTTP transport. + /// This calls `try_on_anvil_with_wallet_and_config` and panics on error. pub fn on_anvil_with_wallet_and_config( self, f: impl FnOnce(alloy_node_bindings::Anvil) -> alloy_node_bindings::Anvil, - ) -> > as ProviderLayer< + ) -> as ProviderLayer< L::Provider, alloy_transport_http::Http, >>::Provider + where + F: TxFiller + + ProviderLayer, Ethereum>, + L: crate::builder::ProviderLayer< + crate::layers::AnvilProvider< + crate::provider::RootProvider>, + alloy_transport_http::Http, + >, + alloy_transport_http::Http, + >, + { + self.try_on_anvil_with_wallet_and_config(f).unwrap() + } + + /// Build this provider with anvil, using an Reqwest HTTP transport. The + /// given function is used to configure the anvil instance. This + /// function configures a wallet backed by anvil keys, and is intended for + /// use in tests. + pub fn try_on_anvil_with_wallet_and_config( + self, + f: impl FnOnce(alloy_node_bindings::Anvil) -> alloy_node_bindings::Anvil, + ) -> AnvilProviderResult< + as ProviderLayer< + L::Provider, + alloy_transport_http::Http, + >>::Provider, + > where F: TxFiller + ProviderLayer, Ethereum>, @@ -439,7 +468,9 @@ impl ProviderBuilder { let url = anvil_layer.endpoint_url(); let default_keys = anvil_layer.instance().keys().to_vec(); - let (default_key, remaining_keys) = default_keys.split_first().expect("no keys available"); + let (default_key, remaining_keys) = default_keys + .split_first() + .ok_or(alloy_node_bindings::anvil::AnvilError::NoKeysAvailable)?; let default_signer = alloy_signer_local::LocalSigner::from(default_key.clone()); let mut wallet = alloy_network::EthereumWallet::from(default_signer); @@ -448,7 +479,7 @@ impl ProviderBuilder { wallet.register_signer(alloy_signer_local::LocalSigner::from(key.clone())) }); - self.wallet(wallet).layer(anvil_layer).on_http(url) + Ok(self.wallet(wallet).layer(anvil_layer).on_http(url)) } } From 4d2d903007a924baec284e827fd0d34a806a0bb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien?= <3535019+leruaa@users.noreply.github.com> Date: Tue, 16 Jul 2024 16:56:54 +0200 Subject: [PATCH 026/186] feat: expose encoded_len_with_signature() (#1063) * feat: expose encoded_len_with_signature() * nit: fmt --- crates/consensus/src/transaction/eip1559.rs | 6 +----- crates/consensus/src/transaction/eip2930.rs | 6 +----- crates/consensus/src/transaction/eip4844.rs | 6 +----- crates/consensus/src/transaction/eip7702.rs | 6 +----- crates/consensus/src/transaction/legacy.rs | 2 +- 5 files changed, 5 insertions(+), 21 deletions(-) diff --git a/crates/consensus/src/transaction/eip1559.rs b/crates/consensus/src/transaction/eip1559.rs index 4bd890e23c0..3d09bc93a5b 100644 --- a/crates/consensus/src/transaction/eip1559.rs +++ b/crates/consensus/src/transaction/eip1559.rs @@ -153,11 +153,7 @@ impl TxEip1559 { /// /// If `with_header` is `true`, the payload length will include the RLP header length. /// If `with_header` is `false`, the payload length will not include the RLP header length. - pub(crate) fn encoded_len_with_signature( - &self, - signature: &Signature, - with_header: bool, - ) -> usize { + pub fn encoded_len_with_signature(&self, signature: &Signature, with_header: bool) -> usize { // this counts the tx fields and signature fields let payload_length = self.fields_len() + signature.rlp_vrs_len(); diff --git a/crates/consensus/src/transaction/eip2930.rs b/crates/consensus/src/transaction/eip2930.rs index 5cc576861d4..621dd15edad 100644 --- a/crates/consensus/src/transaction/eip2930.rs +++ b/crates/consensus/src/transaction/eip2930.rs @@ -131,11 +131,7 @@ impl TxEip2930 { /// /// If `with_header` is `true`, the payload length will include the RLP header length. /// If `with_header` is `false`, the payload length will not include the RLP header length. - pub(crate) fn encoded_len_with_signature( - &self, - signature: &Signature, - with_header: bool, - ) -> usize { + pub fn encoded_len_with_signature(&self, signature: &Signature, with_header: bool) -> usize { // this counts the tx fields and signature fields let payload_length = self.fields_len() + signature.rlp_vrs_len(); diff --git a/crates/consensus/src/transaction/eip4844.rs b/crates/consensus/src/transaction/eip4844.rs index 18d2dfaae62..4c00cbfc825 100644 --- a/crates/consensus/src/transaction/eip4844.rs +++ b/crates/consensus/src/transaction/eip4844.rs @@ -493,11 +493,7 @@ impl TxEip4844 { /// /// If `with_header` is `true`, the payload length will include the RLP header length. /// If `with_header` is `false`, the payload length will not include the RLP header length. - pub(crate) fn encoded_len_with_signature( - &self, - signature: &Signature, - with_header: bool, - ) -> usize { + pub fn encoded_len_with_signature(&self, signature: &Signature, with_header: bool) -> usize { // this counts the tx fields and signature fields let payload_length = self.fields_len() + signature.rlp_vrs_len(); diff --git a/crates/consensus/src/transaction/eip7702.rs b/crates/consensus/src/transaction/eip7702.rs index e8934d474d3..e852cee0ab0 100644 --- a/crates/consensus/src/transaction/eip7702.rs +++ b/crates/consensus/src/transaction/eip7702.rs @@ -161,11 +161,7 @@ impl TxEip7702 { /// /// If `with_header` is `true`, the payload length will include the RLP header length. /// If `with_header` is `false`, the payload length will not include the RLP header length. - pub(crate) fn encoded_len_with_signature( - &self, - signature: &Signature, - with_header: bool, - ) -> usize { + pub fn encoded_len_with_signature(&self, signature: &Signature, with_header: bool) -> usize { // this counts the tx fields and signature fields let payload_length = self.fields_len() + signature.rlp_vrs_len(); diff --git a/crates/consensus/src/transaction/legacy.rs b/crates/consensus/src/transaction/legacy.rs index 4b55bea77b5..6b2fb66ff22 100644 --- a/crates/consensus/src/transaction/legacy.rs +++ b/crates/consensus/src/transaction/legacy.rs @@ -118,7 +118,7 @@ impl TxLegacy { /// Returns what the encoded length should be, if the transaction were RLP encoded with the /// given signature. - pub(crate) fn encoded_len_with_signature(&self, signature: &Signature) -> usize { + pub fn encoded_len_with_signature(&self, signature: &Signature) -> usize { let payload_length = self.fields_len() + signature.rlp_vrs_len(); Header { list: true, payload_length }.length() + payload_length } From bcfecd8ba5b24b90329056076b537d40ccf9d7f0 Mon Sep 17 00:00:00 2001 From: morito Date: Tue, 16 Jul 2024 23:58:37 +0900 Subject: [PATCH 027/186] fix: Trim conflicting key `max_fee_per_blob_gas` from Eip1559 tx type (#1064) --- crates/rpc-types-eth/src/transaction/request.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/rpc-types-eth/src/transaction/request.rs b/crates/rpc-types-eth/src/transaction/request.rs index a1fdd2c50e4..6fae40d2b89 100644 --- a/crates/rpc-types-eth/src/transaction/request.rs +++ b/crates/rpc-types-eth/src/transaction/request.rs @@ -332,6 +332,7 @@ impl TransactionRequest { } TxType::Eip1559 => { self.gas_price = None; + self.max_fee_per_blob_gas = None; self.blob_versioned_hashes = None; self.sidecar = None; } From dfe60ae1c0876a4c2cd6b08965962418c0b34777 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 16 Jul 2024 21:14:41 +0200 Subject: [PATCH 028/186] chore: release 0.2.0 --- CHANGELOG.md | 50 ++++++++++++++++++++++ Cargo.toml | 64 ++++++++++++++-------------- crates/alloy/CHANGELOG.md | 12 ++++++ crates/consensus/CHANGELOG.md | 21 +++++++++ crates/contract/CHANGELOG.md | 12 ++++++ crates/eip7547/CHANGELOG.md | 13 ++++++ crates/eips/CHANGELOG.md | 24 +++++++++++ crates/genesis/CHANGELOG.md | 17 ++++++++ crates/json-rpc/CHANGELOG.md | 11 +++++ crates/network/CHANGELOG.md | 12 ++++++ crates/node-bindings/CHANGELOG.md | 18 ++++++++ crates/provider/CHANGELOG.md | 19 +++++++++ crates/pubsub/CHANGELOG.md | 14 ++++++ crates/rpc-client/CHANGELOG.md | 14 ++++++ crates/rpc-types-admin/CHANGELOG.md | 15 +++++++ crates/rpc-types-anvil/CHANGELOG.md | 13 ++++++ crates/rpc-types-beacon/CHANGELOG.md | 11 +++++ crates/rpc-types-engine/CHANGELOG.md | 16 +++++++ crates/rpc-types-eth/CHANGELOG.md | 26 +++++++++++ crates/rpc-types-mev/CHANGELOG.md | 11 +++++ crates/rpc-types-trace/CHANGELOG.md | 24 +++++++++++ crates/rpc-types-txpool/CHANGELOG.md | 13 ++++++ crates/rpc-types/CHANGELOG.md | 17 ++++++++ crates/serde/CHANGELOG.md | 16 +++++++ crates/signer-aws/CHANGELOG.md | 13 ++++++ crates/signer-gcp/CHANGELOG.md | 13 ++++++ crates/signer-ledger/CHANGELOG.md | 13 ++++++ crates/signer-local/CHANGELOG.md | 14 ++++++ crates/signer-trezor/CHANGELOG.md | 15 +++++++ crates/signer/CHANGELOG.md | 13 ++++++ crates/transport-http/CHANGELOG.md | 13 ++++++ crates/transport-ipc/CHANGELOG.md | 13 ++++++ crates/transport-ws/CHANGELOG.md | 13 ++++++ crates/transport/CHANGELOG.md | 12 ++++++ 34 files changed, 563 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ad37f0c03b5..1f41da2a36f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,55 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Bug Fixes + +- Trim conflicting key `max_fee_per_blob_gas` from Eip1559 tx type ([#1064](https://github.com/alloy-rs/alloy/issues/1064)) +- [provider] Prevent panic from having 0 keys when calling `on_anvil_with_wallet_and_config` ([#1055](https://github.com/alloy-rs/alloy/issues/1055)) +- Require storageKeys value broken bincode serialization from [#955](https://github.com/alloy-rs/alloy/issues/955) ([#1058](https://github.com/alloy-rs/alloy/issues/1058)) +- [provider] Do not overflow LRU cache capacity in ChainStreamPoller ([#1052](https://github.com/alloy-rs/alloy/issues/1052)) +- [admin] Id in NodeInfo is string instead of B256 ([#1038](https://github.com/alloy-rs/alloy/issues/1038)) +- Cargo fmt ([#1044](https://github.com/alloy-rs/alloy/issues/1044)) +- [eip7702] Add correct rlp decode/encode ([#1034](https://github.com/alloy-rs/alloy/issues/1034)) + +### Dependencies + +- [deps] Bump Trezor client to `=0.1.4` to fix signing bug ([#1045](https://github.com/alloy-rs/alloy/issues/1045)) + +### Features + +- Expose encoded_len_with_signature() ([#1063](https://github.com/alloy-rs/alloy/issues/1063)) +- Add 7702 tx type ([#1046](https://github.com/alloy-rs/alloy/issues/1046)) +- [rpc-types-eth] Serde flatten `BlobTransactionSidecar` in tx req ([#1054](https://github.com/alloy-rs/alloy/issues/1054)) +- Add authorization list to rpc transaction and tx receipt types ([#1051](https://github.com/alloy-rs/alloy/issues/1051)) +- Impl `arbitrary` for tx structs ([#1050](https://github.com/alloy-rs/alloy/issues/1050)) +- [core] Update core version ([#1049](https://github.com/alloy-rs/alloy/issues/1049)) +- [otterscan] Add ots slim block and serialze OperationType to int ([#1043](https://github.com/alloy-rs/alloy/issues/1043)) +- Generate valid signed auth signatures ([#1041](https://github.com/alloy-rs/alloy/issues/1041)) +- Add `rpc-types-mev` feature to meta crate ([#1040](https://github.com/alloy-rs/alloy/issues/1040)) +- Add arbitrary to auth ([#1036](https://github.com/alloy-rs/alloy/issues/1036)) +- [genesis] Rm EIP150Hash ([#1039](https://github.com/alloy-rs/alloy/issues/1039)) +- Add hash for 7702 ([#1037](https://github.com/alloy-rs/alloy/issues/1037)) +- Add rpc namespace ([#994](https://github.com/alloy-rs/alloy/issues/994)) + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 +- Make auth mandatory in recovered auth ([#1047](https://github.com/alloy-rs/alloy/issues/1047)) +- Trace output utils ([#1027](https://github.com/alloy-rs/alloy/issues/1027)) +- Fix unnameable types ([#1029](https://github.com/alloy-rs/alloy/issues/1029)) +- Add payloadbodies v2 to capabilities set ([#1025](https://github.com/alloy-rs/alloy/issues/1025)) + +### Refactor + +- Replace `U64` with `u64` ([#1057](https://github.com/alloy-rs/alloy/issues/1057)) + +### Styling + +- Remove proptest in all crates and Arbitrary derives ([#966](https://github.com/alloy-rs/alloy/issues/966)) + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Bug Fixes @@ -45,6 +94,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.1.4 - Update release config - Add helper functions for destructuring auth types ([#1022](https://github.com/alloy-rs/alloy/issues/1022)) - Convert rcp-types-eth block Header to consensus Header ([#1014](https://github.com/alloy-rs/alloy/issues/1014)) diff --git a/Cargo.toml b/Cargo.toml index 76615ab2d70..9f17dd07bd8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = ["crates/*"] resolver = "2" [workspace.package] -version = "0.1.4" +version = "0.2.0" edition = "2021" rust-version = "1.76" authors = ["Alloy Contributors"] @@ -35,37 +35,37 @@ all-features = true rustdoc-args = ["--cfg", "docsrs"] [workspace.dependencies] -alloy-consensus = { version = "0.1", path = "crates/consensus", default-features = false } -alloy-contract = { version = "0.1", path = "crates/contract", default-features = false } -alloy-eips = { version = "0.1", path = "crates/eips", default-features = false } -alloy-eip7547 = { version = "0.1", path = "crates/eip7547", default-features = false } -alloy-genesis = { version = "0.1", path = "crates/genesis", default-features = false } -alloy-json-rpc = { version = "0.1", path = "crates/json-rpc", default-features = false } -alloy-network = { version = "0.1", path = "crates/network", default-features = false } -alloy-node-bindings = { version = "0.1", path = "crates/node-bindings", default-features = false } -alloy-provider = { version = "0.1", path = "crates/provider", default-features = false } -alloy-pubsub = { version = "0.1", path = "crates/pubsub", default-features = false } -alloy-rpc-client = { version = "0.1", path = "crates/rpc-client", default-features = false } -alloy-rpc-types-admin = { version = "0.1", path = "crates/rpc-types-admin", default-features = false } -alloy-rpc-types-anvil = { version = "0.1", path = "crates/rpc-types-anvil", default-features = false } -alloy-rpc-types-beacon = { version = "0.1", path = "crates/rpc-types-beacon", default-features = false } -alloy-rpc-types-engine = { version = "0.1", path = "crates/rpc-types-engine", default-features = false } -alloy-rpc-types-eth = { version = "0.1", path = "crates/rpc-types-eth", default-features = false } -alloy-rpc-types-mev = { version = "0.1", path = "crates/rpc-types-mev", default-features = false } -alloy-rpc-types-trace = { version = "0.1", path = "crates/rpc-types-trace", default-features = false } -alloy-rpc-types-txpool = { version = "0.1", path = "crates/rpc-types-txpool", default-features = false } -alloy-rpc-types = { version = "0.1", path = "crates/rpc-types", default-features = false } -alloy-serde = { version = "0.1", path = "crates/serde", default-features = false } -alloy-signer = { version = "0.1", path = "crates/signer", default-features = false } -alloy-signer-aws = { version = "0.1", path = "crates/signer-aws", default-features = false } -alloy-signer-gcp = { version = "0.1", path = "crates/signer-gcp", default-features = false } -alloy-signer-ledger = { version = "0.1", path = "crates/signer-ledger", default-features = false } -alloy-signer-local = { version = "0.1", path = "crates/signer-local", default-features = false } -alloy-signer-trezor = { version = "0.1", path = "crates/signer-trezor", default-features = false } -alloy-transport = { version = "0.1", path = "crates/transport", default-features = false } -alloy-transport-http = { version = "0.1", path = "crates/transport-http", default-features = false } -alloy-transport-ipc = { version = "0.1", path = "crates/transport-ipc", default-features = false } -alloy-transport-ws = { version = "0.1", path = "crates/transport-ws", default-features = false } +alloy-consensus = { version = "0.2", path = "crates/consensus", default-features = false } +alloy-contract = { version = "0.2", path = "crates/contract", default-features = false } +alloy-eips = { version = "0.2", path = "crates/eips", default-features = false } +alloy-eip7547 = { version = "0.2", path = "crates/eip7547", default-features = false } +alloy-genesis = { version = "0.2", path = "crates/genesis", default-features = false } +alloy-json-rpc = { version = "0.2", path = "crates/json-rpc", default-features = false } +alloy-network = { version = "0.2", path = "crates/network", default-features = false } +alloy-node-bindings = { version = "0.2", path = "crates/node-bindings", default-features = false } +alloy-provider = { version = "0.2", path = "crates/provider", default-features = false } +alloy-pubsub = { version = "0.2", path = "crates/pubsub", default-features = false } +alloy-rpc-client = { version = "0.2", path = "crates/rpc-client", default-features = false } +alloy-rpc-types-admin = { version = "0.2", path = "crates/rpc-types-admin", default-features = false } +alloy-rpc-types-anvil = { version = "0.2", path = "crates/rpc-types-anvil", default-features = false } +alloy-rpc-types-beacon = { version = "0.2", path = "crates/rpc-types-beacon", default-features = false } +alloy-rpc-types-engine = { version = "0.2", path = "crates/rpc-types-engine", default-features = false } +alloy-rpc-types-eth = { version = "0.2", path = "crates/rpc-types-eth", default-features = false } +alloy-rpc-types-mev = { version = "0.2", path = "crates/rpc-types-mev", default-features = false } +alloy-rpc-types-trace = { version = "0.2", path = "crates/rpc-types-trace", default-features = false } +alloy-rpc-types-txpool = { version = "0.2", path = "crates/rpc-types-txpool", default-features = false } +alloy-rpc-types = { version = "0.2", path = "crates/rpc-types", default-features = false } +alloy-serde = { version = "0.2", path = "crates/serde", default-features = false } +alloy-signer = { version = "0.2", path = "crates/signer", default-features = false } +alloy-signer-aws = { version = "0.2", path = "crates/signer-aws", default-features = false } +alloy-signer-gcp = { version = "0.2", path = "crates/signer-gcp", default-features = false } +alloy-signer-ledger = { version = "0.2", path = "crates/signer-ledger", default-features = false } +alloy-signer-local = { version = "0.2", path = "crates/signer-local", default-features = false } +alloy-signer-trezor = { version = "0.2", path = "crates/signer-trezor", default-features = false } +alloy-transport = { version = "0.2", path = "crates/transport", default-features = false } +alloy-transport-http = { version = "0.2", path = "crates/transport-http", default-features = false } +alloy-transport-ipc = { version = "0.2", path = "crates/transport-ipc", default-features = false } +alloy-transport-ws = { version = "0.2", path = "crates/transport-ws", default-features = false } alloy-core = { version = "0.7.7", default-features = false } alloy-dyn-abi = { version = "0.7.7", default-features = false } diff --git a/crates/alloy/CHANGELOG.md b/crates/alloy/CHANGELOG.md index 0054e2d5f9d..87fe5d40423 100644 --- a/crates/alloy/CHANGELOG.md +++ b/crates/alloy/CHANGELOG.md @@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Features + +- Add `rpc-types-mev` feature to meta crate ([#1040](https://github.com/alloy-rs/alloy/issues/1040)) + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Dependencies @@ -17,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.1.4 - Release 0.1.3 (-p alloy) ## [0.1.3](https://github.com/alloy-rs/alloy/releases/tag/v0.1.3) - 2024-06-25 diff --git a/crates/consensus/CHANGELOG.md b/crates/consensus/CHANGELOG.md index 9dd423660f7..f866a1a7d3c 100644 --- a/crates/consensus/CHANGELOG.md +++ b/crates/consensus/CHANGELOG.md @@ -5,12 +5,33 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Features + +- Expose encoded_len_with_signature() ([#1063](https://github.com/alloy-rs/alloy/issues/1063)) +- Add 7702 tx type ([#1046](https://github.com/alloy-rs/alloy/issues/1046)) +- Impl `arbitrary` for tx structs ([#1050](https://github.com/alloy-rs/alloy/issues/1050)) + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 + +### Styling + +- Remove proptest in all crates and Arbitrary derives ([#966](https://github.com/alloy-rs/alloy/issues/966)) + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Features - Impl Transaction for TxEnvelope ([#1006](https://github.com/alloy-rs/alloy/issues/1006)) +### Miscellaneous Tasks + +- Release 0.1.4 + ### Other - Remove signature.v parity before calculating tx hash ([#893](https://github.com/alloy-rs/alloy/issues/893)) diff --git a/crates/contract/CHANGELOG.md b/crates/contract/CHANGELOG.md index 269bef1c998..43945c28fe7 100644 --- a/crates/contract/CHANGELOG.md +++ b/crates/contract/CHANGELOG.md @@ -5,8 +5,20 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 +- Fix unnameable types ([#1029](https://github.com/alloy-rs/alloy/issues/1029)) + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 +### Miscellaneous Tasks + +- Release 0.1.4 + ### Other - Allow to convert CallBuilderTo TransactionRequest ([#981](https://github.com/alloy-rs/alloy/issues/981)) diff --git a/crates/eip7547/CHANGELOG.md b/crates/eip7547/CHANGELOG.md index 63de946cb56..516d9874b5f 100644 --- a/crates/eip7547/CHANGELOG.md +++ b/crates/eip7547/CHANGELOG.md @@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 + +## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 + +### Miscellaneous Tasks + +- Release 0.1.4 + ## [0.1.3](https://github.com/alloy-rs/alloy/releases/tag/v0.1.3) - 2024-06-25 ### Miscellaneous Tasks diff --git a/crates/eips/CHANGELOG.md b/crates/eips/CHANGELOG.md index 2b5e4180ef9..382eff41105 100644 --- a/crates/eips/CHANGELOG.md +++ b/crates/eips/CHANGELOG.md @@ -5,6 +5,29 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Bug Fixes + +- Require storageKeys value broken bincode serialization from [#955](https://github.com/alloy-rs/alloy/issues/955) ([#1058](https://github.com/alloy-rs/alloy/issues/1058)) +- Cargo fmt ([#1044](https://github.com/alloy-rs/alloy/issues/1044)) +- [eip7702] Add correct rlp decode/encode ([#1034](https://github.com/alloy-rs/alloy/issues/1034)) + +### Features + +- Add authorization list to rpc transaction and tx receipt types ([#1051](https://github.com/alloy-rs/alloy/issues/1051)) +- Generate valid signed auth signatures ([#1041](https://github.com/alloy-rs/alloy/issues/1041)) +- Add arbitrary to auth ([#1036](https://github.com/alloy-rs/alloy/issues/1036)) +- Add hash for 7702 ([#1037](https://github.com/alloy-rs/alloy/issues/1037)) + +### Miscellaneous Tasks + +- Make auth mandatory in recovered auth ([#1047](https://github.com/alloy-rs/alloy/issues/1047)) + +### Styling + +- Remove proptest in all crates and Arbitrary derives ([#966](https://github.com/alloy-rs/alloy/issues/966)) + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Features @@ -15,6 +38,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.1.4 - Add helper functions for destructuring auth types ([#1022](https://github.com/alloy-rs/alloy/issues/1022)) - Clean up 7702 encoding ([#1000](https://github.com/alloy-rs/alloy/issues/1000)) diff --git a/crates/genesis/CHANGELOG.md b/crates/genesis/CHANGELOG.md index e2606021b06..a44f3b900df 100644 --- a/crates/genesis/CHANGELOG.md +++ b/crates/genesis/CHANGELOG.md @@ -5,10 +5,27 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Features + +- [genesis] Rm EIP150Hash ([#1039](https://github.com/alloy-rs/alloy/issues/1039)) + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Miscellaneous Tasks +- Release 0.1.4 + +## [0.1.3](https://github.com/alloy-rs/alloy/releases/tag/v0.1.3) - 2024-06-25 + +### Miscellaneous Tasks + - Release 0.1.3 ## [0.1.2](https://github.com/alloy-rs/alloy/releases/tag/v0.1.2) - 2024-06-19 diff --git a/crates/json-rpc/CHANGELOG.md b/crates/json-rpc/CHANGELOG.md index f5542048dfa..ac25e512b06 100644 --- a/crates/json-rpc/CHANGELOG.md +++ b/crates/json-rpc/CHANGELOG.md @@ -5,12 +5,23 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Features - [transport] Retry layer ([#849](https://github.com/alloy-rs/alloy/issues/849)) +### Miscellaneous Tasks + +- Release 0.1.4 + ## [0.1.3](https://github.com/alloy-rs/alloy/releases/tag/v0.1.3) - 2024-06-25 ### Miscellaneous Tasks diff --git a/crates/network/CHANGELOG.md b/crates/network/CHANGELOG.md index 2fd7b90e814..9b2aa65b1bf 100644 --- a/crates/network/CHANGELOG.md +++ b/crates/network/CHANGELOG.md @@ -5,12 +5,24 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 +- Fix unnameable types ([#1029](https://github.com/alloy-rs/alloy/issues/1029)) + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Features - [network] Block context in ReceiptResponse ([#1003](https://github.com/alloy-rs/alloy/issues/1003)) +### Miscellaneous Tasks + +- Release 0.1.4 + ## [0.1.3](https://github.com/alloy-rs/alloy/releases/tag/v0.1.3) - 2024-06-25 ### Features diff --git a/crates/node-bindings/CHANGELOG.md b/crates/node-bindings/CHANGELOG.md index e3e487cb7b9..e65787af257 100644 --- a/crates/node-bindings/CHANGELOG.md +++ b/crates/node-bindings/CHANGELOG.md @@ -5,10 +5,28 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Bug Fixes + +- [provider] Prevent panic from having 0 keys when calling `on_anvil_with_wallet_and_config` ([#1055](https://github.com/alloy-rs/alloy/issues/1055)) +- [admin] Id in NodeInfo is string instead of B256 ([#1038](https://github.com/alloy-rs/alloy/issues/1038)) + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Miscellaneous Tasks +- Release 0.1.4 + +## [0.1.3](https://github.com/alloy-rs/alloy/releases/tag/v0.1.3) - 2024-06-25 + +### Miscellaneous Tasks + - Release 0.1.3 ## [0.1.2](https://github.com/alloy-rs/alloy/releases/tag/v0.1.2) - 2024-06-19 diff --git a/crates/provider/CHANGELOG.md b/crates/provider/CHANGELOG.md index 3015bc97f3b..14bfae1615d 100644 --- a/crates/provider/CHANGELOG.md +++ b/crates/provider/CHANGELOG.md @@ -5,6 +5,24 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Bug Fixes + +- [provider] Prevent panic from having 0 keys when calling `on_anvil_with_wallet_and_config` ([#1055](https://github.com/alloy-rs/alloy/issues/1055)) +- [provider] Do not overflow LRU cache capacity in ChainStreamPoller ([#1052](https://github.com/alloy-rs/alloy/issues/1052)) +- [admin] Id in NodeInfo is string instead of B256 ([#1038](https://github.com/alloy-rs/alloy/issues/1038)) + +### Features + +- Add rpc namespace ([#994](https://github.com/alloy-rs/alloy/issues/994)) + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 +- Fix unnameable types ([#1029](https://github.com/alloy-rs/alloy/issues/1029)) + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Bug Fixes @@ -21,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.1.4 - [provider] Simplify nonce filler ([#976](https://github.com/alloy-rs/alloy/issues/976)) ### Testing diff --git a/crates/pubsub/CHANGELOG.md b/crates/pubsub/CHANGELOG.md index 3636086dc32..7403bfabfd2 100644 --- a/crates/pubsub/CHANGELOG.md +++ b/crates/pubsub/CHANGELOG.md @@ -5,10 +5,24 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 +- Fix unnameable types ([#1029](https://github.com/alloy-rs/alloy/issues/1029)) + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Miscellaneous Tasks +- Release 0.1.4 + +## [0.1.3](https://github.com/alloy-rs/alloy/releases/tag/v0.1.3) - 2024-06-25 + +### Miscellaneous Tasks + - Release 0.1.3 - Nightly clippy ([#947](https://github.com/alloy-rs/alloy/issues/947)) diff --git a/crates/rpc-client/CHANGELOG.md b/crates/rpc-client/CHANGELOG.md index b45e3e3b480..e4fc5179bd2 100644 --- a/crates/rpc-client/CHANGELOG.md +++ b/crates/rpc-client/CHANGELOG.md @@ -5,10 +5,24 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 +- Fix unnameable types ([#1029](https://github.com/alloy-rs/alloy/issues/1029)) + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Miscellaneous Tasks +- Release 0.1.4 + +## [0.1.3](https://github.com/alloy-rs/alloy/releases/tag/v0.1.3) - 2024-06-25 + +### Miscellaneous Tasks + - Release 0.1.3 ## [0.1.2](https://github.com/alloy-rs/alloy/releases/tag/v0.1.2) - 2024-06-19 diff --git a/crates/rpc-types-admin/CHANGELOG.md b/crates/rpc-types-admin/CHANGELOG.md index e9617aa23af..370e48150e6 100644 --- a/crates/rpc-types-admin/CHANGELOG.md +++ b/crates/rpc-types-admin/CHANGELOG.md @@ -5,12 +5,27 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Bug Fixes + +- [admin] Id in NodeInfo is string instead of B256 ([#1038](https://github.com/alloy-rs/alloy/issues/1038)) + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Features - Add missing admin_* methods ([#991](https://github.com/alloy-rs/alloy/issues/991)) +### Miscellaneous Tasks + +- Release 0.1.4 + ## [0.1.3](https://github.com/alloy-rs/alloy/releases/tag/v0.1.3) - 2024-06-25 ### Miscellaneous Tasks diff --git a/crates/rpc-types-anvil/CHANGELOG.md b/crates/rpc-types-anvil/CHANGELOG.md index 02c88540f34..2d120db226c 100644 --- a/crates/rpc-types-anvil/CHANGELOG.md +++ b/crates/rpc-types-anvil/CHANGELOG.md @@ -5,10 +5,23 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Miscellaneous Tasks +- Release 0.1.4 + +## [0.1.3](https://github.com/alloy-rs/alloy/releases/tag/v0.1.3) - 2024-06-25 + +### Miscellaneous Tasks + - Release 0.1.3 ## [0.1.2](https://github.com/alloy-rs/alloy/releases/tag/v0.1.2) - 2024-06-19 diff --git a/crates/rpc-types-beacon/CHANGELOG.md b/crates/rpc-types-beacon/CHANGELOG.md index 0c6c1b5b1a1..2f16fd707a6 100644 --- a/crates/rpc-types-beacon/CHANGELOG.md +++ b/crates/rpc-types-beacon/CHANGELOG.md @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Features @@ -12,6 +19,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add consolidation requests to v4 payload ([#1013](https://github.com/alloy-rs/alloy/issues/1013)) - Add submit block request query ([#995](https://github.com/alloy-rs/alloy/issues/995)) +### Miscellaneous Tasks + +- Release 0.1.4 + ## [0.1.3](https://github.com/alloy-rs/alloy/releases/tag/v0.1.3) - 2024-06-25 ### Miscellaneous Tasks diff --git a/crates/rpc-types-engine/CHANGELOG.md b/crates/rpc-types-engine/CHANGELOG.md index 48a39ea180a..349a15fd96f 100644 --- a/crates/rpc-types-engine/CHANGELOG.md +++ b/crates/rpc-types-engine/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 +- Add payloadbodies v2 to capabilities set ([#1025](https://github.com/alloy-rs/alloy/issues/1025)) + +### Refactor + +- Replace `U64` with `u64` ([#1057](https://github.com/alloy-rs/alloy/issues/1057)) + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Features @@ -12,6 +24,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add execution payloadbodyv2 ([#1012](https://github.com/alloy-rs/alloy/issues/1012)) - Add consolidation requests to v4 payload ([#1013](https://github.com/alloy-rs/alloy/issues/1013)) +### Miscellaneous Tasks + +- Release 0.1.4 + ## [0.1.3](https://github.com/alloy-rs/alloy/releases/tag/v0.1.3) - 2024-06-25 ### Miscellaneous Tasks diff --git a/crates/rpc-types-eth/CHANGELOG.md b/crates/rpc-types-eth/CHANGELOG.md index 02b76489156..85720423448 100644 --- a/crates/rpc-types-eth/CHANGELOG.md +++ b/crates/rpc-types-eth/CHANGELOG.md @@ -5,6 +5,31 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Bug Fixes + +- Trim conflicting key `max_fee_per_blob_gas` from Eip1559 tx type ([#1064](https://github.com/alloy-rs/alloy/issues/1064)) + +### Features + +- [rpc-types-eth] Serde flatten `BlobTransactionSidecar` in tx req ([#1054](https://github.com/alloy-rs/alloy/issues/1054)) +- Add authorization list to rpc transaction and tx receipt types ([#1051](https://github.com/alloy-rs/alloy/issues/1051)) + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 +- Fix unnameable types ([#1029](https://github.com/alloy-rs/alloy/issues/1029)) + +### Refactor + +- Replace `U64` with `u64` ([#1057](https://github.com/alloy-rs/alloy/issues/1057)) + +### Styling + +- Remove proptest in all crates and Arbitrary derives ([#966](https://github.com/alloy-rs/alloy/issues/966)) + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Features @@ -15,6 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.1.4 - Convert rcp-types-eth block Header to consensus Header ([#1014](https://github.com/alloy-rs/alloy/issues/1014)) - Make wrapped index value pub ([#988](https://github.com/alloy-rs/alloy/issues/988)) diff --git a/crates/rpc-types-mev/CHANGELOG.md b/crates/rpc-types-mev/CHANGELOG.md index ff00b47b972..f1c0bc3a696 100644 --- a/crates/rpc-types-mev/CHANGELOG.md +++ b/crates/rpc-types-mev/CHANGELOG.md @@ -5,12 +5,23 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Features - Add missing eth bundle args ([#978](https://github.com/alloy-rs/alloy/issues/978)) +### Miscellaneous Tasks + +- Release 0.1.4 + ### Other - Update builders to vector of strings in privacy struct ([#983](https://github.com/alloy-rs/alloy/issues/983)) diff --git a/crates/rpc-types-trace/CHANGELOG.md b/crates/rpc-types-trace/CHANGELOG.md index 446969cb8fa..f7b1b92a24e 100644 --- a/crates/rpc-types-trace/CHANGELOG.md +++ b/crates/rpc-types-trace/CHANGELOG.md @@ -5,6 +5,26 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Features + +- [otterscan] Add ots slim block and serialze OperationType to int ([#1043](https://github.com/alloy-rs/alloy/issues/1043)) + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 +- Trace output utils ([#1027](https://github.com/alloy-rs/alloy/issues/1027)) + +### Refactor + +- Replace `U64` with `u64` ([#1057](https://github.com/alloy-rs/alloy/issues/1057)) + +### Styling + +- Remove proptest in all crates and Arbitrary derives ([#966](https://github.com/alloy-rs/alloy/issues/966)) + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Bug Fixes @@ -16,6 +36,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [otterscan] Add output for TraceEntry ([#1001](https://github.com/alloy-rs/alloy/issues/1001)) - Add helpers for trace action ([#982](https://github.com/alloy-rs/alloy/issues/982)) +### Miscellaneous Tasks + +- Release 0.1.4 + ## [0.1.3](https://github.com/alloy-rs/alloy/releases/tag/v0.1.3) - 2024-06-25 ### Miscellaneous Tasks diff --git a/crates/rpc-types-txpool/CHANGELOG.md b/crates/rpc-types-txpool/CHANGELOG.md index bcffcbc0bdd..34c1bd210a1 100644 --- a/crates/rpc-types-txpool/CHANGELOG.md +++ b/crates/rpc-types-txpool/CHANGELOG.md @@ -5,10 +5,23 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Miscellaneous Tasks +- Release 0.1.4 + +## [0.1.3](https://github.com/alloy-rs/alloy/releases/tag/v0.1.3) - 2024-06-25 + +### Miscellaneous Tasks + - Release 0.1.3 ## [0.1.2](https://github.com/alloy-rs/alloy/releases/tag/v0.1.2) - 2024-06-19 diff --git a/crates/rpc-types/CHANGELOG.md b/crates/rpc-types/CHANGELOG.md index 0f921bbc142..aff7a29039a 100644 --- a/crates/rpc-types/CHANGELOG.md +++ b/crates/rpc-types/CHANGELOG.md @@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Features + +- Add rpc namespace ([#994](https://github.com/alloy-rs/alloy/issues/994)) + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 + +## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 + +### Miscellaneous Tasks + +- Release 0.1.4 + ## [0.1.3](https://github.com/alloy-rs/alloy/releases/tag/v0.1.3) - 2024-06-25 ### Features diff --git a/crates/serde/CHANGELOG.md b/crates/serde/CHANGELOG.md index 9054ea1042b..9897d637c17 100644 --- a/crates/serde/CHANGELOG.md +++ b/crates/serde/CHANGELOG.md @@ -5,8 +5,24 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Miscellaneous Tasks + +- Fix unnameable types ([#1029](https://github.com/alloy-rs/alloy/issues/1029)) + +### Styling + +- Remove proptest in all crates and Arbitrary derives ([#966](https://github.com/alloy-rs/alloy/issues/966)) + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 +### Miscellaneous Tasks + +- Release 0.1.4 + +## [0.1.3](https://github.com/alloy-rs/alloy/releases/tag/v0.1.3) - 2024-06-25 + ### Bug Fixes - Deserialization of null storage keys in AccessListItem ([#955](https://github.com/alloy-rs/alloy/issues/955)) diff --git a/crates/signer-aws/CHANGELOG.md b/crates/signer-aws/CHANGELOG.md index 7b986cd7348..8d0a305c90b 100644 --- a/crates/signer-aws/CHANGELOG.md +++ b/crates/signer-aws/CHANGELOG.md @@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 + +## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 + +### Miscellaneous Tasks + +- Release 0.1.4 + ## [0.1.3](https://github.com/alloy-rs/alloy/releases/tag/v0.1.3) - 2024-06-25 ### Miscellaneous Tasks diff --git a/crates/signer-gcp/CHANGELOG.md b/crates/signer-gcp/CHANGELOG.md index 843a7766f71..fe18142eb7d 100644 --- a/crates/signer-gcp/CHANGELOG.md +++ b/crates/signer-gcp/CHANGELOG.md @@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 + +## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 + +### Miscellaneous Tasks + +- Release 0.1.4 + ## [0.1.3](https://github.com/alloy-rs/alloy/releases/tag/v0.1.3) - 2024-06-25 ### Miscellaneous Tasks diff --git a/crates/signer-ledger/CHANGELOG.md b/crates/signer-ledger/CHANGELOG.md index 2b2d0644f6e..aeb71f23047 100644 --- a/crates/signer-ledger/CHANGELOG.md +++ b/crates/signer-ledger/CHANGELOG.md @@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 + +## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 + +### Miscellaneous Tasks + +- Release 0.1.4 + ## [0.1.3](https://github.com/alloy-rs/alloy/releases/tag/v0.1.3) - 2024-06-25 ### Miscellaneous Tasks diff --git a/crates/signer-local/CHANGELOG.md b/crates/signer-local/CHANGELOG.md index d8fae0e572a..defe425da03 100644 --- a/crates/signer-local/CHANGELOG.md +++ b/crates/signer-local/CHANGELOG.md @@ -5,10 +5,24 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 +- Fix unnameable types ([#1029](https://github.com/alloy-rs/alloy/issues/1029)) + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Miscellaneous Tasks +- Release 0.1.4 + +## [0.1.3](https://github.com/alloy-rs/alloy/releases/tag/v0.1.3) - 2024-06-25 + +### Miscellaneous Tasks + - Release 0.1.3 ## [0.1.2](https://github.com/alloy-rs/alloy/releases/tag/v0.1.2) - 2024-06-19 diff --git a/crates/signer-trezor/CHANGELOG.md b/crates/signer-trezor/CHANGELOG.md index 9a792659f9f..e8df4185f60 100644 --- a/crates/signer-trezor/CHANGELOG.md +++ b/crates/signer-trezor/CHANGELOG.md @@ -5,12 +5,27 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Dependencies + +- [deps] Bump Trezor client to `=0.1.4` to fix signing bug ([#1045](https://github.com/alloy-rs/alloy/issues/1045)) + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Bug Fixes - [signer-trezor] Fix zero gas price when sending legacy tx with trezor ([#977](https://github.com/alloy-rs/alloy/issues/977)) +### Miscellaneous Tasks + +- Release 0.1.4 + ## [0.1.3](https://github.com/alloy-rs/alloy/releases/tag/v0.1.3) - 2024-06-25 ### Miscellaneous Tasks diff --git a/crates/signer/CHANGELOG.md b/crates/signer/CHANGELOG.md index af99be8213a..ca994bf36f9 100644 --- a/crates/signer/CHANGELOG.md +++ b/crates/signer/CHANGELOG.md @@ -5,10 +5,23 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Miscellaneous Tasks +- Release 0.1.4 + +## [0.1.3](https://github.com/alloy-rs/alloy/releases/tag/v0.1.3) - 2024-06-25 + +### Miscellaneous Tasks + - Release 0.1.3 ## [0.1.2](https://github.com/alloy-rs/alloy/releases/tag/v0.1.2) - 2024-06-19 diff --git a/crates/transport-http/CHANGELOG.md b/crates/transport-http/CHANGELOG.md index 22e62e313d8..146c016b946 100644 --- a/crates/transport-http/CHANGELOG.md +++ b/crates/transport-http/CHANGELOG.md @@ -5,10 +5,23 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Miscellaneous Tasks +- Release 0.1.4 + +## [0.1.3](https://github.com/alloy-rs/alloy/releases/tag/v0.1.3) - 2024-06-25 + +### Miscellaneous Tasks + - Release 0.1.3 ## [0.1.2](https://github.com/alloy-rs/alloy/releases/tag/v0.1.2) - 2024-06-19 diff --git a/crates/transport-ipc/CHANGELOG.md b/crates/transport-ipc/CHANGELOG.md index 2cf8f7f6a2d..edbae0d18dc 100644 --- a/crates/transport-ipc/CHANGELOG.md +++ b/crates/transport-ipc/CHANGELOG.md @@ -5,8 +5,21 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 +### Miscellaneous Tasks + +- Release 0.1.4 + +## [0.1.3](https://github.com/alloy-rs/alloy/releases/tag/v0.1.3) - 2024-06-25 + ### Bug Fixes - Continue reading ipc on large data ([#958](https://github.com/alloy-rs/alloy/issues/958)) diff --git a/crates/transport-ws/CHANGELOG.md b/crates/transport-ws/CHANGELOG.md index 26a45ac7cf6..59b028483d8 100644 --- a/crates/transport-ws/CHANGELOG.md +++ b/crates/transport-ws/CHANGELOG.md @@ -5,10 +5,23 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Miscellaneous Tasks +- Release 0.1.4 + +## [0.1.3](https://github.com/alloy-rs/alloy/releases/tag/v0.1.3) - 2024-06-25 + +### Miscellaneous Tasks + - Release 0.1.3 ## [0.1.2](https://github.com/alloy-rs/alloy/releases/tag/v0.1.2) - 2024-06-19 diff --git a/crates/transport/CHANGELOG.md b/crates/transport/CHANGELOG.md index c23edc0ab1e..e1b248fc7b2 100644 --- a/crates/transport/CHANGELOG.md +++ b/crates/transport/CHANGELOG.md @@ -5,12 +5,24 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 + +### Miscellaneous Tasks + +- Release 0.2.0 +- Release 0.2.0 +- Fix unnameable types ([#1029](https://github.com/alloy-rs/alloy/issues/1029)) + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Features - [transport] Retry layer ([#849](https://github.com/alloy-rs/alloy/issues/849)) +### Miscellaneous Tasks + +- Release 0.1.4 + ## [0.1.3](https://github.com/alloy-rs/alloy/releases/tag/v0.1.3) - 2024-06-25 ### Miscellaneous Tasks From 05eca12ead2e5d790fdb4c96a4f1df6b94d823ab Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Tue, 16 Jul 2024 22:26:39 +0300 Subject: [PATCH 029/186] docs: update links to use docs.rs (#1066) --- README.md | 2 +- crates/transport/README.md | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 7f618a9823e..20268026730 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ Alloy connects applications to blockchains. Alloy is a rewrite of [`ethers-rs`] from the ground up, with exciting new -features, high performance, and excellent [docs](https://alloy-rs.github.io/alloy/). +features, high performance, and excellent [docs](https://docs.rs/alloy). We also have a [book](https://alloy.rs/) on all things Alloy and many [examples](https://github.com/alloy-rs/examples) to help you get started. diff --git a/crates/transport/README.md b/crates/transport/README.md index e4fa5a8a163..5dec20b73b8 100644 --- a/crates/transport/README.md +++ b/crates/transport/README.md @@ -15,7 +15,7 @@ with JSON-RPC servers that provide the standard Ethereum RPC endpoints, or the [alloy-rpc-client] crate, which provides a low-level JSON-RPC API without the specific Ethereum endpoints. -[alloy-provider]: https://alloy-rs.github.io/alloy/alloy_provider/index.html +[alloy-provider]: https://docs.rs/alloy_provider/ [tower `Service`]: https://docs.rs/tower/latest/tower/trait.Service.html ### Transports @@ -27,7 +27,7 @@ Alloy maintains the following transports: [alloy-pubsub]. - [alloy-transport-ipc]: JSON-RPC via IPC, supports pubsub via [alloy-pubsub]. -[alloy-transport-http]: https://alloy-rs.github.io/alloy/alloy_transport_http/index.html -[alloy-transport-ws]: https://alloy-rs.github.io/alloy/alloy_transport_ws/index.html -[alloy-transport-ipc]: https://alloy-rs.github.io/alloy/alloy_transport_ipc/index.html -[alloy-pubsub]: https://alloy-rs.github.io/alloy/alloy_pubsub/index.html \ No newline at end of file +[alloy-transport-http]: https://docs.rs/alloy_transport_http/ +[alloy-transport-ws]: https://docs.rs/alloy_transport_ws/ +[alloy-transport-ipc]: https://docs.rs/alloy_transport_ipc/ +[alloy-pubsub]: https://docs.rs/alloy_pubsub/ From c715e576d2b49a459c5fd5d8cfa77ad594837226 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 16 Jul 2024 22:30:46 +0200 Subject: [PATCH 030/186] chore: bump jsonrpsee 0.24 (#1067) --- crates/rpc-types-engine/Cargo.toml | 2 +- crates/rpc-types-eth/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/rpc-types-engine/Cargo.toml b/crates/rpc-types-engine/Cargo.toml index fe489961498..dbc30871e26 100644 --- a/crates/rpc-types-engine/Cargo.toml +++ b/crates/rpc-types-engine/Cargo.toml @@ -35,7 +35,7 @@ serde = { workspace = true, features = ["derive"] } thiserror.workspace = true # jsonrpsee -jsonrpsee-types = { version = "0.23", optional = true } +jsonrpsee-types = { version = "0.24", optional = true } # jwt jsonwebtoken = "9.3.0" diff --git a/crates/rpc-types-eth/Cargo.toml b/crates/rpc-types-eth/Cargo.toml index e0bd123c1e7..e1c998b73e0 100644 --- a/crates/rpc-types-eth/Cargo.toml +++ b/crates/rpc-types-eth/Cargo.toml @@ -35,7 +35,7 @@ thiserror.workspace = true arbitrary = { version = "1.3", features = ["derive"], optional = true } # jsonrpsee -jsonrpsee-types = { version = "0.23", optional = true } +jsonrpsee-types = { version = "0.24", optional = true } alloy-sol-types.workspace = true [dev-dependencies] From 423a4c53c1bffdfb2acca2daee60215194f7711d Mon Sep 17 00:00:00 2001 From: tesseract <146037313+DoTheBestToGetTheBest@users.noreply.github.com> Date: Tue, 16 Jul 2024 16:17:23 -0700 Subject: [PATCH 031/186] feat(provider) : introduction to eth_sendRawTransactionConditional RPC endpoint type (#1009) * Update request.rs * Update trait.rs * clippy * Update trait.rs * Update trait.rs * added reference and camelCase serde * Update request.rs * Update lib.rs * Create eip4337.rs * Update eip4337.rs * fix serde * reorder --------- Co-authored-by: Matthias Seitz --- crates/rpc-types-eth/src/eip4337.rs | 41 +++++++++++++++++++ crates/rpc-types-eth/src/lib.rs | 3 ++ .../rpc-types-eth/src/transaction/request.rs | 1 - 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 crates/rpc-types-eth/src/eip4337.rs diff --git a/crates/rpc-types-eth/src/eip4337.rs b/crates/rpc-types-eth/src/eip4337.rs new file mode 100644 index 00000000000..0a43da2f44f --- /dev/null +++ b/crates/rpc-types-eth/src/eip4337.rs @@ -0,0 +1,41 @@ +use alloy_primitives::{Address, BlockNumber, B256, U256}; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +/// Options for conditional raw transaction submissions. +// reference for the implementation +// See also +#[derive(Debug, Serialize, Deserialize, Clone, Default)] +#[serde(rename_all = "camelCase")] +pub struct ConditionalOptions { + /// A map of account addresses to their expected storage states. + /// Each account can have a specified storage root or explicit slot-value pairs. + #[serde(default)] + pub known_accounts: HashMap, + /// The minimal block number at which the transaction can be included. + /// `None` indicates no minimum block number constraint. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub block_number_min: Option, + /// The maximal block number at which the transaction can be included. + /// `None` indicates no maximum block number constraint. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub block_number_max: Option, + /// The minimal timestamp at which the transaction can be included. + /// `None` indicates no minimum timestamp constraint. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub timestamp_min: Option, + /// The maximal timestamp at which the transaction can be included. + /// `None` indicates no maximum timestamp constraint. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub timestamp_max: Option, +} + +/// Represents the expected state of an account for a transaction to be conditionally accepted. +#[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(untagged)] +pub enum AccountStorage { + /// Expected storage root hash of the account. + RootHash(B256), + /// Explicit storage slots and their expected values. + Slots(HashMap), +} diff --git a/crates/rpc-types-eth/src/lib.rs b/crates/rpc-types-eth/src/lib.rs index 46a5f3b4bd6..2219acba233 100644 --- a/crates/rpc-types-eth/src/lib.rs +++ b/crates/rpc-types-eth/src/lib.rs @@ -46,3 +46,6 @@ pub use transaction::*; mod work; pub use work::Work; + +/// This module provides implementations for EIP-4337. +pub mod eip4337; diff --git a/crates/rpc-types-eth/src/transaction/request.rs b/crates/rpc-types-eth/src/transaction/request.rs index 6fae40d2b89..36c85addd3c 100644 --- a/crates/rpc-types-eth/src/transaction/request.rs +++ b/crates/rpc-types-eth/src/transaction/request.rs @@ -8,7 +8,6 @@ use alloy_consensus::{ use alloy_primitives::{Address, Bytes, ChainId, TxKind, B256, U256}; use serde::{Deserialize, Serialize}; use std::hash::Hash; - /// Represents _all_ transaction requests to/from RPC. #[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] From 067cc464bd1357e745653709db051707b949cc6b Mon Sep 17 00:00:00 2001 From: zerosnacks <95942363+zerosnacks@users.noreply.github.com> Date: Thu, 18 Jul 2024 18:03:47 +0200 Subject: [PATCH 032/186] bug: `alloy-consensus` should use `alloy_primitives::Sealable` (#1072) * use Sealable and Sealed from alloy-primitives * fix path in docs --- crates/consensus/src/header.rs | 7 +-- crates/consensus/src/lib.rs | 3 +- crates/consensus/src/receipt/receipts.rs | 2 +- crates/consensus/src/sealed.rs | 67 ------------------------ 4 files changed, 6 insertions(+), 73 deletions(-) delete mode 100644 crates/consensus/src/sealed.rs diff --git a/crates/consensus/src/header.rs b/crates/consensus/src/header.rs index 91f17b797af..f593b873929 100644 --- a/crates/consensus/src/header.rs +++ b/crates/consensus/src/header.rs @@ -1,9 +1,10 @@ -use crate::Sealable; use alloy_eips::{ eip1559::{calc_next_block_base_fee, BaseFeeParams}, eip4844::{calc_blob_gasprice, calc_excess_blob_gas}, }; -use alloy_primitives::{b256, keccak256, Address, BlockNumber, Bloom, Bytes, B256, B64, U256}; +use alloy_primitives::{ + b256, keccak256, Address, BlockNumber, Bloom, Bytes, Sealable, B256, B64, U256, +}; use alloy_rlp::{ length_of_length, Buf, BufMut, Decodable, Encodable, EMPTY_LIST_CODE, EMPTY_STRING_CODE, }; @@ -161,7 +162,7 @@ impl Default for Header { } impl Sealable for Header { - fn hash(&self) -> B256 { + fn hash_slow(&self) -> B256 { self.hash_slow() } } diff --git a/crates/consensus/src/lib.rs b/crates/consensus/src/lib.rs index da2e1cb1dcc..5cef218eab9 100644 --- a/crates/consensus/src/lib.rs +++ b/crates/consensus/src/lib.rs @@ -42,8 +42,7 @@ pub use alloy_eips::eip4844::{ #[cfg(feature = "kzg")] pub use alloy_eips::eip4844::env_settings::EnvKzgSettings; -mod sealed; -pub use sealed::{Sealable, Sealed}; +pub use alloy_primitives::{Sealable, Sealed}; mod signed; pub use signed::Signed; diff --git a/crates/consensus/src/receipt/receipts.rs b/crates/consensus/src/receipt/receipts.rs index f57e648c3e4..e9476a81f72 100644 --- a/crates/consensus/src/receipt/receipts.rs +++ b/crates/consensus/src/receipt/receipts.rs @@ -107,7 +107,7 @@ impl From> for Receipt { /// This convenience type allows us to lazily calculate the bloom filter for a /// receipt, similar to [`Sealed`]. /// -/// [`Sealed`]: crate::sealed::Sealed +/// [`Sealed`]: crate::Sealed #[derive(Clone, Debug, Default, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] diff --git a/crates/consensus/src/sealed.rs b/crates/consensus/src/sealed.rs deleted file mode 100644 index 9db492d7523..00000000000 --- a/crates/consensus/src/sealed.rs +++ /dev/null @@ -1,67 +0,0 @@ -use alloy_primitives::B256; - -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -/// A consensus hashable item, with its memoized hash. -/// -/// We do not implement -pub struct Sealed { - /// The inner item - inner: T, - /// Its hash. - seal: B256, -} - -impl core::ops::Deref for Sealed { - type Target = T; - - fn deref(&self) -> &Self::Target { - self.inner() - } -} - -impl Sealed { - /// Instantiate without performing the hash. This should be used carefully. - pub const fn new_unchecked(inner: T, seal: B256) -> Self { - Self { inner, seal } - } - - /// Decompose into parts. - pub fn into_parts(self) -> (T, B256) { - (self.inner, self.seal) - } - - /// Get the inner item. - #[inline(always)] - pub const fn inner(&self) -> &T { - &self.inner - } - - /// Get the hash. - #[inline(always)] - pub const fn seal(&self) -> B256 { - self.seal - } - - /// Geth the hash (alias for [`Self::seal`]). - #[inline(always)] - pub const fn hash(&self) -> B256 { - self.seal() - } -} - -/// Sealable objects. -pub trait Sealable: Sized { - /// Calculate the seal hash, this may be slow. - fn hash(&self) -> B256; - - /// Seal the object by calculating the hash. This may be slow. - fn seal_slow(self) -> Sealed { - let seal = self.hash(); - Sealed::new_unchecked(self, seal) - } - - /// Instantiate an unchecked seal. This should be used with caution. - fn seal_unchecked(self, seal: B256) -> Sealed { - Sealed::new_unchecked(self, seal) - } -} From 0ddad90de0c82de34349d1a2712ec227833ad846 Mon Sep 17 00:00:00 2001 From: Luca Provini Date: Fri, 19 Jul 2024 14:26:15 +0200 Subject: [PATCH 033/186] Added stages to the sync info rpc type (#1079) * added stages detail * boxed enum * from hashmap to vec with helper type * serde alias and renames and dos * Update crates/rpc-types-eth/src/syncing.rs Co-authored-by: Matthias Seitz * Update crates/rpc-types-eth/src/syncing.rs Co-authored-by: Matthias Seitz * property to pub --------- Co-authored-by: Matthias Seitz --- crates/rpc-types-eth/src/syncing.rs | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/crates/rpc-types-eth/src/syncing.rs b/crates/rpc-types-eth/src/syncing.rs index 0be858e61cd..68bfd1d0f68 100644 --- a/crates/rpc-types-eth/src/syncing.rs +++ b/crates/rpc-types-eth/src/syncing.rs @@ -3,7 +3,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::collections::BTreeMap; /// Syncing info -#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct SyncInfo { /// Starting block @@ -16,6 +16,22 @@ pub struct SyncInfo { pub warp_chunks_amount: Option, /// Warp sync snapshot chunks processed. pub warp_chunks_processed: Option, + /// The details of the sync stages as an hashmap + /// where the key is the name of the stage and the value is the block number. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub stages: Option>, +} + +/// The detail of the sync stages. +#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct Stage { + /// The name of the sync stage. + #[serde(alias = "stage_name")] + pub name: String, + /// Indicates the progress of the sync stage. + #[serde(alias = "block_number", with = "alloy_serde::quantity")] + pub block: u64, } /// Peers info @@ -99,10 +115,10 @@ pub struct PipProtocolInfo { } /// Sync status -#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[derive(Clone, Debug, PartialEq, Eq)] pub enum SyncStatus { /// Info when syncing - Info(SyncInfo), + Info(Box), /// Not syncing None, } @@ -117,7 +133,7 @@ impl<'de> Deserialize<'de> for SyncStatus { enum Syncing { /// When client is synced to the highest block, eth_syncing with return "false" None(bool), - IsSyncing(SyncInfo), + IsSyncing(Box), } match Syncing::deserialize(deserializer)? { From 062e96e025bbb5a53ec4b4d2c95d25f7a67c5e39 Mon Sep 17 00:00:00 2001 From: Luca Provini Date: Fri, 19 Jul 2024 14:30:56 +0200 Subject: [PATCH 034/186] removing async get account (#1080) --- crates/provider/src/provider/trait.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/crates/provider/src/provider/trait.rs b/crates/provider/src/provider/trait.rs index 9ccd9c93f27..7d4cc1f889e 100644 --- a/crates/provider/src/provider/trait.rs +++ b/crates/provider/src/provider/trait.rs @@ -241,10 +241,7 @@ pub trait Provider: /// Retrieves account information ([Account](alloy_consensus::Account)) for the given [Address] /// at the particular [BlockId]. - async fn get_account( - &self, - address: Address, - ) -> RpcWithBlock { + fn get_account(&self, address: Address) -> RpcWithBlock { RpcWithBlock::new(self.weak_client(), "eth_getAccount", address) } From a414b4a4ac1fcabca383e8fe4b3812052f4ada94 Mon Sep 17 00:00:00 2001 From: StackOverflowExcept1on <109800286+StackOverflowExcept1on@users.noreply.github.com> Date: Fri, 19 Jul 2024 16:27:30 +0300 Subject: [PATCH 035/186] fix(node-bindings): backport fix from ethers-rs (#1081) --- crates/node-bindings/src/anvil.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/node-bindings/src/anvil.rs b/crates/node-bindings/src/anvil.rs index 62903e9c2e7..a20cdaaf12a 100644 --- a/crates/node-bindings/src/anvil.rs +++ b/crates/node-bindings/src/anvil.rs @@ -318,7 +318,7 @@ impl Anvil { let mut child = cmd.spawn().map_err(AnvilError::SpawnError)?; - let stdout = child.stdout.as_mut().ok_or(AnvilError::NoStderr)?; + let stdout = child.stdout.take().ok_or(AnvilError::NoStderr)?; let start = Instant::now(); let mut reader = BufReader::new(stdout); From 7f7b665579a8b4a29a694b6ce0c20b6731d6f9b2 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Fri, 19 Jul 2024 20:17:13 +0200 Subject: [PATCH 036/186] feat(consensus): add `From` for `Request` (#1083) consensus: add From for Request --- crates/consensus/src/request.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crates/consensus/src/request.rs b/crates/consensus/src/request.rs index 6b6cb3211a9..6087d856f19 100644 --- a/crates/consensus/src/request.rs +++ b/crates/consensus/src/request.rs @@ -41,6 +41,12 @@ impl From for Request { } } +impl From for Request { + fn from(v: ConsolidationRequest) -> Self { + Self::ConsolidationRequest(v) + } +} + impl Request { /// Whether this is a [`DepositRequest`]. pub const fn is_deposit_request(&self) -> bool { From 4520b2c7b6b6dbbe69d41ce3024e758eafb67113 Mon Sep 17 00:00:00 2001 From: Dan Cline <6798349+Rjected@users.noreply.github.com> Date: Fri, 19 Jul 2024 14:19:00 -0400 Subject: [PATCH 037/186] fix(eips): make SignedAuthorizationList arbitrary less fallible (#1084) --- crates/eips/Cargo.toml | 2 ++ crates/eips/src/eip7702/auth_list.rs | 21 +++++++++++++++------ crates/eips/src/lib.rs | 5 +++++ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/crates/eips/Cargo.toml b/crates/eips/Cargo.toml index 4c2a1866ca5..aaff60fa33d 100644 --- a/crates/eips/Cargo.toml +++ b/crates/eips/Cargo.toml @@ -41,6 +41,7 @@ arbitrary = { workspace = true, features = ["derive"], optional = true } # for signed authorization list arbitrary k256 = { workspace = true, optional = true } +rand = { workspace = true, optional = true } [dev-dependencies] alloy-primitives = { workspace = true, features = [ @@ -80,6 +81,7 @@ arbitrary = [ "std", "kzg-sidecar", "dep:arbitrary", + "dep:rand", "alloy-primitives/arbitrary", "alloy-serde?/arbitrary", ] diff --git a/crates/eips/src/eip7702/auth_list.rs b/crates/eips/src/eip7702/auth_list.rs index d7ef4142639..64280012b5b 100644 --- a/crates/eips/src/eip7702/auth_list.rs +++ b/crates/eips/src/eip7702/auth_list.rs @@ -177,10 +177,15 @@ impl Deref for SignedAuthorization { #[cfg(all(any(test, feature = "arbitrary"), feature = "k256"))] impl<'a> arbitrary::Arbitrary<'a> for SignedAuthorization { fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { - use k256::ecdsa::{signature::hazmat::PrehashSigner, SigningKey}; - let key_bytes = u.arbitrary::<[u8; 32]>()?; - let signing_key = SigningKey::from_bytes(&key_bytes.into()) - .map_err(|_| arbitrary::Error::IncorrectFormat)?; + use k256::{ + ecdsa::{signature::hazmat::PrehashSigner, SigningKey}, + NonZeroScalar, + }; + use rand::{rngs::StdRng, SeedableRng}; + + let rng_seed = u.arbitrary::<[u8; 32]>()?; + let mut rand_gen = StdRng::from_seed(rng_seed); + let signing_key: SigningKey = NonZeroScalar::random(&mut rand_gen).into(); let inner = u.arbitrary::()?; let signature_hash = inner.signature_hash(); @@ -307,7 +312,6 @@ impl Deref for OptionalNonce { mod tests { use super::*; use alloy_primitives::{hex, Signature}; - use arbitrary::Arbitrary; use core::str::FromStr; fn test_encode_decode_roundtrip(auth: Authorization) { @@ -367,10 +371,15 @@ mod tests { assert_eq!(decoded, auth); } - #[cfg(feature = "k256")] + #[cfg(all(feature = "arbitrary", feature = "k256"))] #[test] fn test_arbitrary_auth() { + use arbitrary::Arbitrary; let mut unstructured = arbitrary::Unstructured::new(b"unstructured auth"); + // try this multiple times + let _auth = SignedAuthorization::arbitrary(&mut unstructured).unwrap(); + let _auth = SignedAuthorization::arbitrary(&mut unstructured).unwrap(); + let _auth = SignedAuthorization::arbitrary(&mut unstructured).unwrap(); let _auth = SignedAuthorization::arbitrary(&mut unstructured).unwrap(); } } diff --git a/crates/eips/src/lib.rs b/crates/eips/src/lib.rs index 393ba4f343e..b1111f8eeb5 100644 --- a/crates/eips/src/lib.rs +++ b/crates/eips/src/lib.rs @@ -11,6 +11,11 @@ #[macro_use] extern crate alloc; +// To ensure no unused imports, since signed auth list requires arbitrary _and_ k256 features, but +// is only enabled using the `arbitrary` feature. +#[cfg(all(not(feature = "k256"), feature = "arbitrary"))] +use rand as _; + pub mod eip1559; pub use eip1559::calc_next_block_base_fee; From 2be7dde2828f7756fc5556a19bd5b3601952620e Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Sat, 20 Jul 2024 09:27:05 +0200 Subject: [PATCH 038/186] chore: export rpc account type (#1075) --- crates/rpc-types-eth/src/account.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/crates/rpc-types-eth/src/account.rs b/crates/rpc-types-eth/src/account.rs index 10d6e9e3b16..439e24dd5a3 100644 --- a/crates/rpc-types-eth/src/account.rs +++ b/crates/rpc-types-eth/src/account.rs @@ -1,6 +1,10 @@ use alloy_primitives::{Address, Bytes, B256, B512, U256}; use alloy_serde::storage::JsonStorageKey; use serde::{Deserialize, Serialize}; + +// re-export account type for `eth_getAccount` +pub use alloy_consensus::Account; + /// Account information. #[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] pub struct AccountInfo { From 2dea91e21b83f8902a9b0033a623393d33c78155 Mon Sep 17 00:00:00 2001 From: nk_ysg Date: Mon, 22 Jul 2024 01:47:02 +0800 Subject: [PATCH 039/186] chore : fix typos (#1087) * chore : fix typos * revert infura --- crates/consensus/src/account.rs | 2 +- crates/rpc-types-admin/src/admin.rs | 2 +- crates/rpc-types-mev/src/mev_calls.rs | 2 +- crates/rpc-types-trace/src/otterscan.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/consensus/src/account.rs b/crates/consensus/src/account.rs index 66d189f349a..66ff20dc741 100644 --- a/crates/consensus/src/account.rs +++ b/crates/consensus/src/account.rs @@ -19,7 +19,7 @@ pub struct Account { } impl Account { - /// Compute hash as committed to in the MPT trie without memoizing. + /// Compute hash as committed to in the MPT trie without memorizing. pub fn trie_hash_slow(&self) -> B256 { keccak256(alloy_rlp::encode(self)) } diff --git a/crates/rpc-types-admin/src/admin.rs b/crates/rpc-types-admin/src/admin.rs index d227d117670..65dc2af2f5d 100644 --- a/crates/rpc-types-admin/src/admin.rs +++ b/crates/rpc-types-admin/src/admin.rs @@ -213,7 +213,7 @@ pub struct PeerEvent { pub kind: PeerEventType, /// The peer's enode ID. pub peer: String, - /// An error ocurred on the peer. + /// An error occurred on the peer. #[serde(default, skip_serializing_if = "Option::is_none")] pub error: Option, /// The protocol of the peer. diff --git a/crates/rpc-types-mev/src/mev_calls.rs b/crates/rpc-types-mev/src/mev_calls.rs index f85ecfa294a..ea4b3950751 100644 --- a/crates/rpc-types-mev/src/mev_calls.rs +++ b/crates/rpc-types-mev/src/mev_calls.rs @@ -312,7 +312,7 @@ mod tests { } #[test] - fn can_dererialize_sim_response() { + fn can_deserialize_sim_response() { let expected = r#" { "success": true, diff --git a/crates/rpc-types-trace/src/otterscan.rs b/crates/rpc-types-trace/src/otterscan.rs index f5a71778cb2..a56ed47366e 100644 --- a/crates/rpc-types-trace/src/otterscan.rs +++ b/crates/rpc-types-trace/src/otterscan.rs @@ -280,7 +280,7 @@ mod tests { } #[test] - fn test_otterscan_interal_operation() { + fn test_otterscan_internal_operation() { let s = r#"{ "type": 0, "from": "0xea593b730d745fb5fe01b6d20e6603915252c6bf", From 67f024a0220451f36535ad427f9c6af88312fe8c Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Mon, 22 Jul 2024 09:40:09 +0200 Subject: [PATCH 040/186] feat(json-rpc): implement `From for Id` and `From for Id` (#1088) feat(json-rpc): implement From for Id and From for Id --- crates/json-rpc/src/common.rs | 16 ++++++++++++++-- crates/rpc-client/src/client.rs | 2 +- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/crates/json-rpc/src/common.rs b/crates/json-rpc/src/common.rs index 5c23e0fae16..c47228446fd 100644 --- a/crates/json-rpc/src/common.rs +++ b/crates/json-rpc/src/common.rs @@ -32,6 +32,18 @@ pub enum Id { None, } +impl From for Id { + fn from(value: u64) -> Self { + Self::Number(value) + } +} + +impl From for Id { + fn from(value: String) -> Self { + Self::String(value) + } +} + impl Display for Id { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { @@ -70,14 +82,14 @@ impl<'de> Deserialize<'de> for Id { where E: serde::de::Error, { - Ok(Id::Number(v)) + Ok(v.into()) } fn visit_str(self, v: &str) -> Result where E: serde::de::Error, { - Ok(Id::String(v.to_owned())) + Ok(v.to_owned().into()) } fn visit_none(self) -> Result diff --git a/crates/rpc-client/src/client.rs b/crates/rpc-client/src/client.rs index 75ed70c99cb..e52ca93278a 100644 --- a/crates/rpc-client/src/client.rs +++ b/crates/rpc-client/src/client.rs @@ -255,7 +255,7 @@ impl RpcClientInner { /// Reserve a request ID u64. #[inline] pub fn next_id(&self) -> Id { - Id::Number(self.increment_id()) + self.increment_id().into() } } From 7d67e9cd1fcccbd24ea499cb733d4478ca0827b1 Mon Sep 17 00:00:00 2001 From: tesseract <146037313+DoTheBestToGetTheBest@users.noreply.github.com> Date: Tue, 23 Jul 2024 01:43:04 -0700 Subject: [PATCH 041/186] feat(eip): make 7702 auth recovery fallible (#1082) * ake 7702 auth recovery fallible * Update auth_list.rs * Update auth_list.rs * clippy * clippy * Update auth_list.rs * Update crates/eips/src/eip7702/auth_list.rs Co-authored-by: Matthias Seitz * Update auth_list.rs * Update crates/eips/src/eip7702/auth_list.rs Co-authored-by: Oliver * Update crates/eips/src/eip7702/auth_list.rs Co-authored-by: Oliver * chore: add is fns --------- Co-authored-by: Matthias Seitz Co-authored-by: Oliver --- crates/eips/src/eip7702/auth_list.rs | 70 +++++++++++++++++++++------- 1 file changed, 54 insertions(+), 16 deletions(-) diff --git a/crates/eips/src/eip7702/auth_list.rs b/crates/eips/src/eip7702/auth_list.rs index 64280012b5b..bfb0db9203c 100644 --- a/crates/eips/src/eip7702/auth_list.rs +++ b/crates/eips/src/eip7702/auth_list.rs @@ -9,6 +9,37 @@ use alloy_rlp::{ }; use core::hash::{Hash, Hasher}; +/// Represents the outcome of an attempt to recover the authority from an authorization. +/// It can either be valid (containing an [`Address`]) or invalid (indicating recovery failure). +#[derive(Debug, Clone, Hash, Eq, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub enum RecoveredAuthority { + /// Indicates a successfully recovered authority address. + Valid(Address), + /// Indicates a failed recovery attempt where no valid address could be recovered. + Invalid, +} + +impl RecoveredAuthority { + /// Returns an optional address if valid. + pub const fn address(&self) -> Option
{ + match *self { + Self::Valid(address) => Some(address), + Self::Invalid => None, + } + } + + /// Returns true if the authority is valid. + pub const fn is_valid(&self) -> bool { + matches!(self, Self::Valid(_)) + } + + /// Returns true if the authority is invalid. + pub const fn is_invalid(&self) -> bool { + matches!(self, Self::Invalid) + } +} + /// An unsigned EIP-7702 authorization. #[derive(Debug, Clone, Hash, RlpEncodable, RlpDecodable, Eq, PartialEq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] @@ -158,11 +189,12 @@ impl SignedAuthorization { /// Recover the authority and transform the signed authorization into a /// [`RecoveredAuthorization`]. - pub fn try_into_recovered( - self, - ) -> Result { - let authority = self.recover_authority()?; - Ok(RecoveredAuthorization { inner: self.inner, authority }) + pub fn into_recovered(self) -> RecoveredAuthorization { + let authority_result = self.recover_authority(); + let authority = + authority_result.map_or(RecoveredAuthority::Invalid, RecoveredAuthority::Valid); + + RecoveredAuthorization { inner: self.inner, authority } } } @@ -205,35 +237,41 @@ impl<'a> arbitrary::Arbitrary<'a> for SignedAuthorization { pub struct RecoveredAuthorization { #[cfg_attr(feature = "serde", serde(flatten))] inner: Authorization, - authority: Address, + /// The result of the authority recovery process, which can either be a valid address or + /// indicate a failure. + authority: RecoveredAuthority, } impl RecoveredAuthorization { /// Instantiate without performing recovery. This should be used carefully. - pub const fn new_unchecked(inner: Authorization, authority: Address) -> Self { + pub const fn new_unchecked(inner: Authorization, authority: RecoveredAuthority) -> Self { Self { inner, authority } } - /// Get the `authority` for the authorization. - pub const fn authority(&self) -> Address { - self.authority + /// Returns an optional address based on the current state of the authority. + pub const fn authority(&self) -> Option
{ + self.authority.address() } /// Splits the authorization into parts. - pub const fn into_parts(self) -> (Authorization, Address) { + pub const fn into_parts(self) -> (Authorization, RecoveredAuthority) { (self.inner, self.authority) } } #[cfg(feature = "k256")] -impl TryFrom for RecoveredAuthorization { - type Error = alloy_primitives::SignatureError; - - fn try_from(value: SignedAuthorization) -> Result { - value.try_into_recovered() +impl From for RecoveredAuthority { + fn from(value: SignedAuthorization) -> Self { + value.into_recovered().authority } } +#[cfg(feature = "k256")] +impl From for RecoveredAuthorization { + fn from(value: SignedAuthorization) -> Self { + value.into_recovered() + } +} impl Deref for RecoveredAuthorization { type Target = Authorization; From 135590eecfd82cf999d549e9440a70e370afe083 Mon Sep 17 00:00:00 2001 From: tesseract <146037313+DoTheBestToGetTheBest@users.noreply.github.com> Date: Tue, 23 Jul 2024 03:31:55 -0700 Subject: [PATCH 042/186] feat(rpc-type-eth) convert vec TxReq to bundle (#1091) * Update call.rs * clippy --- crates/rpc-types-eth/src/call.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/crates/rpc-types-eth/src/call.rs b/crates/rpc-types-eth/src/call.rs index 09f47660e5b..4f4d65c3370 100644 --- a/crates/rpc-types-eth/src/call.rs +++ b/crates/rpc-types-eth/src/call.rs @@ -12,6 +12,13 @@ pub struct Bundle { pub block_override: Option, } +impl From> for Bundle { + /// Converts a `TransactionRequest` into a `Bundle`. + fn from(tx_request: Vec) -> Self { + Self { transactions: tx_request, block_override: None } + } +} + /// State context for callMany #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] #[serde(default, rename_all = "camelCase")] From 338b5b94daddbf8a5bedff3dfc5f4f5c4fcdf177 Mon Sep 17 00:00:00 2001 From: Delweng Date: Wed, 24 Jul 2024 00:33:05 +0800 Subject: [PATCH 043/186] feat(rpc/trace): filter matches with trace (#1090) * feat(trace): filter with TransactionTrace Signed-off-by: jsvisa * wip: add test case Signed-off-by: jsvisa * Revert "wip: add test case" This reverts commit 7f4ca13bab61d1f937564f945b09bd512f855d11. Signed-off-by: jsvisa * add test case Signed-off-by: jsvisa * Update crates/rpc-types-trace/src/filter.rs Co-authored-by: Matthias Seitz * add more docs Signed-off-by: jsvisa --------- Signed-off-by: jsvisa Co-authored-by: Matthias Seitz --- crates/rpc-types-trace/src/filter.rs | 365 ++++++++++++++++++++------- 1 file changed, 269 insertions(+), 96 deletions(-) diff --git a/crates/rpc-types-trace/src/filter.rs b/crates/rpc-types-trace/src/filter.rs index d0fae8e2412..3e17294ad69 100644 --- a/crates/rpc-types-trace/src/filter.rs +++ b/crates/rpc-types-trace/src/filter.rs @@ -1,4 +1,8 @@ //! `trace_filter` types and support +use crate::parity::{ + Action, CallAction, CreateAction, CreateOutput, RewardAction, SelfdestructAction, TraceOutput, + TransactionTrace, +}; use alloy_primitives::Address; use serde::{Deserialize, Serialize}; use std::collections::HashSet; @@ -93,31 +97,96 @@ pub enum TraceFilterMode { Intersection, } -/// Helper type for matching `from` and `to` addresses. Empty sets match all addresses. +/// Address filter. +/// This is a set of addresses to match against. +/// An empty set matches all addresses. +#[derive(Clone, Debug, Default, PartialEq, Eq)] +pub struct AddressFilter(pub HashSet
); + +impl FromIterator
for AddressFilter { + fn from_iter>(iter: I) -> Self { + Self(iter.into_iter().collect()) + } +} + +impl From> for AddressFilter { + fn from(addrs: Vec
) -> Self { + Self::from_iter(addrs) + } +} + +impl AddressFilter { + /// Returns `true` if the given address is in the filter or the filter address set is empty. + pub fn matches(&self, addr: &Address) -> bool { + self.matches_all() || self.0.contains(addr) + } + + /// Returns `true` if the address set is empty. + pub fn matches_all(&self) -> bool { + self.0.is_empty() + } +} + +/// `TraceFilterMatcher` is a filter used for matching `TransactionTrace` based on +/// it's action and result(if available). It allows filtering traces by their mode, from address +/// set, and to address set, and empty address set means match all addresses. #[derive(Clone, Debug, PartialEq, Eq)] pub struct TraceFilterMatcher { mode: TraceFilterMode, - from_addresses: HashSet
, - to_addresses: HashSet
, + from_addresses: AddressFilter, + to_addresses: AddressFilter, } impl TraceFilterMatcher { - /// Returns `true` if the given `from` and `to` addresses match this filter. - pub fn matches(&self, from: Address, to: Option
) -> bool { - match (self.from_addresses.is_empty(), self.to_addresses.is_empty()) { - (true, true) => true, - (false, true) => self.from_addresses.contains(&from), - (true, false) => to.map_or(false, |to_addr| self.to_addresses.contains(&to_addr)), - (false, false) => match self.mode { - TraceFilterMode::Union => { - self.from_addresses.contains(&from) - || to.map_or(false, |to_addr| self.to_addresses.contains(&to_addr)) - } - TraceFilterMode::Intersection => { - self.from_addresses.contains(&from) - && to.map_or(false, |to_addr| self.to_addresses.contains(&to_addr)) - } - }, + /// Returns `true` if the given `TransactionTrace` matches this filter. + /// + /// # Arguments + /// + /// - `trace`: A reference to a `TransactionTrace` to be evaluated against the filter. + /// + /// # Returns + /// + /// - `true` if the transaction trace matches the filter criteria; otherwise, `false`. + /// + /// # Behavior + /// + /// The function evaluates whether the `trace` matches based on its action type: + /// - `Call`: Matches if either the `from` or `to` addresses in the call action match the + /// filter's address criteria. + /// - `Create`: Matches if the `from` address in action matches, and the result's address (if + /// available) matches the filter's address criteria. + /// - `Selfdestruct`: Matches if the `address` and `refund_address` matches the filter's address + /// criteria. + /// - `Reward`: Matches if the `author` address matches the filter's `to_addresses` criteria. + /// + /// The overall result depends on the filter mode: + /// - `Union` mode: The trace matches if either the `from` or `to` address matches. + /// - `Intersection` mode: The trace matches only if both the `from` and `to` addresses match. + pub fn matches(&self, trace: &TransactionTrace) -> bool { + let (from_matches, to_matches) = match trace.action { + Action::Call(CallAction { from, to, .. }) => { + (self.from_addresses.matches(&from), self.to_addresses.matches(&to)) + } + Action::Create(CreateAction { from, .. }) => ( + self.from_addresses.matches(&from), + match trace.result { + Some(TraceOutput::Create(CreateOutput { address: to, .. })) => { + self.to_addresses.matches(&to) + } + _ => self.to_addresses.matches_all(), + }, + ), + Action::Selfdestruct(SelfdestructAction { address, refund_address, .. }) => { + (self.from_addresses.matches(&address), self.to_addresses.matches(&refund_address)) + } + Action::Reward(RewardAction { author, .. }) => { + (self.from_addresses.matches_all(), self.to_addresses.matches(&author)) + } + }; + + match self.mode { + TraceFilterMode::Union => from_matches || to_matches, + TraceFilterMode::Intersection => from_matches && to_matches, } } } @@ -125,6 +194,7 @@ impl TraceFilterMatcher { #[cfg(test)] mod tests { use super::*; + use alloy_primitives::{Bytes, U256}; use serde_json::json; #[test] @@ -137,88 +207,191 @@ mod tests { #[test] fn test_filter_matcher_addresses_unspecified() { - let test_addr_d8 = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045".parse().unwrap(); - let test_addr_16 = "0x160f5f00288e9e1cc8655b327e081566e580a71d".parse().unwrap(); - let filter_json = json!({ - "fromBlock": "0x3", - "toBlock": "0x5", - }); - let filter: TraceFilter = - serde_json::from_value(filter_json).expect("Failed to parse filter"); - let matcher = filter.matcher(); - assert!(matcher.matches(test_addr_d8, None)); - assert!(matcher.matches(test_addr_16, None)); - assert!(matcher.matches(test_addr_d8, Some(test_addr_16))); - assert!(matcher.matches(test_addr_16, Some(test_addr_d8))); - } + let filter_json = json!({ "fromBlock": "0x3", "toBlock": "0x5" }); + let matcher = serde_json::from_value::(filter_json).unwrap().matcher(); + let s = r#"{ + "action": { + "from": "0x66e29f0b6b1b07071f2fde4345d512386cb66f5f", + "callType": "call", + "gas": "0x10bfc", + "input": "0x", + "to": "0x160f5f00288e9e1cc8655b327e081566e580a71d", + "value": "0x244b" + }, + "error": "Reverted", + "result": { + "gasUsed": "0x9daf", + "output": "0x" + }, + "subtraces": 3, + "traceAddress": [], + "type": "call" + }"#; + let trace = serde_json::from_str::(s).unwrap(); - #[test] - fn test_filter_matcher_from_address() { - let test_addr_d8 = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045".parse().unwrap(); - let test_addr_16 = "0x160f5f00288e9e1cc8655b327e081566e580a71d".parse().unwrap(); - let filter_json = json!({ - "fromBlock": "0x3", - "toBlock": "0x5", - "fromAddress": [test_addr_d8] - }); - let filter: TraceFilter = serde_json::from_value(filter_json).unwrap(); - let matcher = filter.matcher(); - assert!(matcher.matches(test_addr_d8, None)); - assert!(!matcher.matches(test_addr_16, None)); - assert!(matcher.matches(test_addr_d8, Some(test_addr_16))); - assert!(!matcher.matches(test_addr_16, Some(test_addr_d8))); + assert!(matcher.matches(&trace)); } #[test] - fn test_filter_matcher_to_address() { - let test_addr_d8 = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045".parse().unwrap(); - let test_addr_16 = "0x160f5f00288e9e1cc8655b327e081566e580a71d".parse().unwrap(); - let filter_json = json!({ - "fromBlock": "0x3", - "toBlock": "0x5", - "toAddress": [test_addr_d8], - }); - let filter: TraceFilter = serde_json::from_value(filter_json).unwrap(); - let matcher = filter.matcher(); - assert!(matcher.matches(test_addr_16, Some(test_addr_d8))); - assert!(!matcher.matches(test_addr_16, None)); - assert!(!matcher.matches(test_addr_d8, Some(test_addr_16))); - } + fn test_filter_matcher() { + let addr0 = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045".parse().unwrap(); + let addr1 = "0x160f5f00288e9e1cc8655b327e081566e580a71d".parse().unwrap(); + let addr2 = "0x160f5f00288e9e1cc8655b327e081566e580a71f".parse().unwrap(); - #[test] - fn test_filter_matcher_both_addresses_union() { - let test_addr_d8 = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045".parse().unwrap(); - let test_addr_16 = "0x160f5f00288e9e1cc8655b327e081566e580a71d".parse().unwrap(); - let filter_json = json!({ - "fromBlock": "0x3", - "toBlock": "0x5", - "fromAddress": [test_addr_16], - "toAddress": [test_addr_d8], - }); - let filter: TraceFilter = serde_json::from_value(filter_json).unwrap(); - let matcher = filter.matcher(); - assert!(matcher.matches(test_addr_16, Some(test_addr_d8))); - assert!(matcher.matches(test_addr_16, None)); - assert!(matcher.matches(test_addr_d8, Some(test_addr_d8))); - assert!(!matcher.matches(test_addr_d8, Some(test_addr_16))); - } + let m0 = TraceFilterMatcher { + mode: TraceFilterMode::Union, + from_addresses: Default::default(), + to_addresses: Default::default(), + }; - #[test] - fn test_filter_matcher_both_addresses_intersection() { - let test_addr_d8 = "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045".parse().unwrap(); - let test_addr_16 = "0x160f5f00288e9e1cc8655b327e081566e580a71d".parse().unwrap(); - let filter_json = json!({ - "fromBlock": "0x3", - "toBlock": "0x5", - "fromAddress": [test_addr_16], - "toAddress": [test_addr_d8], - "mode": "intersection", - }); - let filter: TraceFilter = serde_json::from_value(filter_json).unwrap(); - let matcher = filter.matcher(); - assert!(matcher.matches(test_addr_16, Some(test_addr_d8))); - assert!(!matcher.matches(test_addr_16, None)); - assert!(!matcher.matches(test_addr_d8, Some(test_addr_d8))); - assert!(!matcher.matches(test_addr_d8, Some(test_addr_16))); + let m1 = TraceFilterMatcher { + mode: TraceFilterMode::Union, + from_addresses: AddressFilter::from(vec![addr0]), + to_addresses: Default::default(), + }; + + let m2 = TraceFilterMatcher { + mode: TraceFilterMode::Union, + from_addresses: AddressFilter::from(vec![]), + to_addresses: AddressFilter::from(vec![addr1]), + }; + + let m3 = TraceFilterMatcher { + mode: TraceFilterMode::Union, + from_addresses: AddressFilter::from(vec![addr0]), + to_addresses: AddressFilter::from(vec![addr1]), + }; + + let m4 = TraceFilterMatcher { + mode: TraceFilterMode::Intersection, + from_addresses: Default::default(), + to_addresses: Default::default(), + }; + + let m5 = TraceFilterMatcher { + mode: TraceFilterMode::Intersection, + from_addresses: AddressFilter::from(vec![addr0]), + to_addresses: Default::default(), + }; + + let m6 = TraceFilterMatcher { + mode: TraceFilterMode::Intersection, + from_addresses: Default::default(), + to_addresses: AddressFilter::from(vec![addr1]), + }; + + let m7 = TraceFilterMatcher { + mode: TraceFilterMode::Intersection, + from_addresses: AddressFilter::from(vec![addr0]), + to_addresses: AddressFilter::from(vec![addr1]), + }; + + // normal call 0 + let trace = TransactionTrace { + action: Action::Call(CallAction { from: addr0, to: addr1, ..Default::default() }), + ..Default::default() + }; + assert!(m0.matches(&trace)); + assert!(m1.matches(&trace)); + assert!(m2.matches(&trace)); + assert!(m3.matches(&trace)); + assert!(m4.matches(&trace)); + assert!(m5.matches(&trace)); + assert!(m6.matches(&trace)); + assert!(m7.matches(&trace)); + + // normal call 1 + let trace = TransactionTrace { + action: Action::Call(CallAction { from: addr0, to: addr2, ..Default::default() }), + ..Default::default() + }; + assert!(m0.matches(&trace)); + assert!(m1.matches(&trace)); + assert!(m2.matches(&trace)); + assert!(m3.matches(&trace)); + assert!(m4.matches(&trace)); + assert!(m5.matches(&trace)); + assert!(!m6.matches(&trace)); + assert!(!m7.matches(&trace)); + + // create success + let trace = TransactionTrace { + action: Action::Create(CreateAction { + from: addr0, + gas: 10240, + init: Bytes::new(), + value: U256::from(0), + }), + result: Some(TraceOutput::Create(CreateOutput { + address: addr1, + code: Bytes::new(), + gas_used: 1025, + })), + ..Default::default() + }; + assert!(m0.matches(&trace)); + assert!(m1.matches(&trace)); + assert!(m2.matches(&trace)); + assert!(m3.matches(&trace)); + assert!(m4.matches(&trace)); + assert!(m5.matches(&trace)); + assert!(m6.matches(&trace)); + assert!(m7.matches(&trace)); + + // create failure + let trace = TransactionTrace { + action: Action::Create(CreateAction { + from: addr0, + gas: 100, + init: Bytes::new(), + value: U256::from(0), + }), + error: Some("out of gas".into()), + ..Default::default() + }; + assert!(m0.matches(&trace)); + assert!(m1.matches(&trace)); + assert!(m2.matches(&trace)); + assert!(m3.matches(&trace)); + assert!(m4.matches(&trace)); + assert!(m5.matches(&trace)); + assert!(!m6.matches(&trace)); + assert!(!m7.matches(&trace)); + + // selfdestruct + let trace = TransactionTrace { + action: Action::Selfdestruct(SelfdestructAction { + address: addr0, + refund_address: addr1, + balance: U256::from(0), + }), + ..Default::default() + }; + assert!(m0.matches(&trace)); + assert!(m1.matches(&trace)); + assert!(m2.matches(&trace)); + assert!(m3.matches(&trace)); + assert!(m4.matches(&trace)); + assert!(m5.matches(&trace)); + assert!(m6.matches(&trace)); + assert!(m7.matches(&trace)); + + // reward + let trace = TransactionTrace { + action: Action::Reward(RewardAction { + author: addr0, + reward_type: crate::parity::RewardType::Block, + value: U256::from(0), + }), + ..Default::default() + }; + assert!(m0.matches(&trace)); + assert!(m1.matches(&trace)); + assert!(m2.matches(&trace)); + assert!(!m3.matches(&trace)); + assert!(m4.matches(&trace)); + assert!(!m5.matches(&trace)); + assert!(!m6.matches(&trace)); + assert!(!m7.matches(&trace)); } } From 24364ac62684aa0ead17ef34f381ebee81d2efdb Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Wed, 24 Jul 2024 00:39:13 +0200 Subject: [PATCH 044/186] typo: fix typo in genesis (#1096) --- crates/genesis/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/genesis/src/lib.rs b/crates/genesis/src/lib.rs index 20156ad2818..76407a08a2e 100644 --- a/crates/genesis/src/lib.rs +++ b/crates/genesis/src/lib.rs @@ -64,8 +64,8 @@ pub struct Genesis { } impl Genesis { - /// Creates a chain config for Clique using the given chain id. - /// and funds the given address with max coins. + /// Creates a chain config for Clique using the given chain id and funds the given address with + /// max coins. /// /// Enables all hard forks up to London at genesis. pub fn clique_genesis(chain_id: u64, signer_addr: Address) -> Self { From 315f9a2c7f42c3329b807fb37c4631f0d1fcd51e Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Wed, 24 Jul 2024 11:18:54 +0200 Subject: [PATCH 045/186] feat: enable more features transitively in meta crate (#1097) --- crates/alloy/Cargo.toml | 8 ++++---- crates/transport/Cargo.toml | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/crates/alloy/Cargo.toml b/crates/alloy/Cargo.toml index a1733b0c4ef..fefbbaac9f4 100644 --- a/crates/alloy/Cargo.toml +++ b/crates/alloy/Cargo.toml @@ -131,7 +131,7 @@ network = ["dep:alloy-network"] node-bindings = ["dep:alloy-node-bindings", "alloy-provider?/anvil-node"] # providers -providers = ["dep:alloy-provider", "rpc-client", "eips"] +providers = ["dep:alloy-provider", "rpc-client", "transports", "eips"] provider-http = ["providers", "transport-http"] provider-ws = ["providers", "alloy-provider?/ws", "transport-ws"] provider-ipc = ["providers", "alloy-provider?/ipc", "transport-ipc"] @@ -184,9 +184,9 @@ pubsub = [ # rpc rpc = [] json-rpc = ["rpc", "dep:alloy-json-rpc"] -rpc-client = ["rpc", "dep:alloy-rpc-client"] -rpc-client-ws = ["rpc-client", "alloy-rpc-client?/ws"] -rpc-client-ipc = ["rpc-client", "alloy-rpc-client?/ipc"] +rpc-client = ["rpc", "transports", "transport-http", "dep:alloy-rpc-client"] +rpc-client-ws = ["rpc-client", "transport-ws", "alloy-rpc-client?/ws"] +rpc-client-ipc = ["rpc-client", "transport-ipc", "alloy-rpc-client?/ipc"] rpc-types = ["rpc", "dep:alloy-rpc-types", "alloy-rpc-types?/eth"] rpc-types-admin = [ "rpc-types", diff --git a/crates/transport/Cargo.toml b/crates/transport/Cargo.toml index 89c3cca99d3..d6e013f308d 100644 --- a/crates/transport/Cargo.toml +++ b/crates/transport/Cargo.toml @@ -36,5 +36,4 @@ tokio = { workspace = true, features = ["rt", "time"] } wasm-bindgen-futures = { version = "0.4", optional = true } [features] - wasm-bindgen = ["dep:wasm-bindgen-futures"] From f2d80032056e715a283be08c84063abf1b47957f Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Wed, 24 Jul 2024 21:18:40 +0800 Subject: [PATCH 046/186] feat: add helper for decoding custom errors (#1098) * feat: add helper for decoding custom errors * use find_map --- crates/json-rpc/Cargo.toml | 1 + crates/json-rpc/src/response/error.rs | 61 ++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/crates/json-rpc/Cargo.toml b/crates/json-rpc/Cargo.toml index 9a2deef43c8..81a2d6b9b28 100644 --- a/crates/json-rpc/Cargo.toml +++ b/crates/json-rpc/Cargo.toml @@ -24,3 +24,4 @@ serde.workspace = true serde_json = { workspace = true, features = ["std", "raw_value"] } thiserror.workspace = true tracing.workspace = true +alloy-sol-types.workspace = true diff --git a/crates/json-rpc/src/response/error.rs b/crates/json-rpc/src/response/error.rs index c6de4dba544..edf94315d26 100644 --- a/crates/json-rpc/src/response/error.rs +++ b/crates/json-rpc/src/response/error.rs @@ -1,8 +1,10 @@ +use alloy_primitives::Bytes; +use alloy_sol_types::SolInterface; use serde::{ de::{DeserializeOwned, MapAccess, Visitor}, Deserialize, Deserializer, Serialize, }; -use serde_json::value::RawValue; +use serde_json::{value::RawValue, Value}; use std::{borrow::Borrow, fmt, marker::PhantomData}; /// A JSONRPC-2.0 error object. @@ -67,6 +69,18 @@ impl ErrorPayload { } } +/// Recursively traverses the value, looking for hex data that it can extract. +/// +/// Inspired by ethers-js logic: +/// +fn spelunk_revert(value: &Value) -> Option { + match value { + Value::String(s) => s.parse().ok(), + Value::Object(o) => o.values().find_map(spelunk_revert), + _ => None, + } +} + impl fmt::Display for ErrorPayload { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "error code {}: {}", self.code, self.message) @@ -224,10 +238,38 @@ where _ => Err(self), } } + + /// Attempt to extract revert data from the JsonRpcError be recursively + /// traversing the error's data field + /// + /// This returns the first hex it finds in the data object, and its + /// behavior may change with `serde_json` internal changes. + /// + /// If no hex object is found, it will return an empty bytes IFF the error + /// is a revert + /// + /// Inspired by ethers-js logic: + /// + pub fn as_revert_data(&self) -> Option { + if self.message.contains("revert") { + let value = Value::deserialize(self.data.as_ref()?.borrow()).ok()?; + spelunk_revert(&value) + } else { + None + } + } + + /// Extracts revert data and tries decoding it into given custom errors set. + pub fn as_decoded_error(&self, validate: bool) -> Option { + self.as_revert_data().and_then(|data| E::abi_decode(&data, validate).ok()) + } } #[cfg(test)] mod test { + use alloy_primitives::U256; + use alloy_sol_types::sol; + use super::BorrowedErrorPayload; use crate::ErrorPayload; @@ -265,4 +307,21 @@ mod test { assert_eq!(payload.message, "20/second request limit reached - reduce calls per second or upgrade your account at quicknode.com"); assert!(payload.data.is_none()); } + + #[test] + fn custom_error_decoding() { + sol!( + library Errors { + error SomeCustomError(uint256 a); + } + ); + + let json = r#"{"code":3,"message":"execution reverted: ","data":"0x810f00230000000000000000000000000000000000000000000000000000000000000001"}"#; + let payload: ErrorPayload = serde_json::from_str(json).unwrap(); + + let Errors::ErrorsErrors::SomeCustomError(value) = + payload.as_decoded_error::(false).unwrap(); + + assert_eq!(value.a, U256::from(1)); + } } From 8ff415d9882b41a310ee36acb6d54e7c06d85a30 Mon Sep 17 00:00:00 2001 From: tesseract <146037313+DoTheBestToGetTheBest@users.noreply.github.com> Date: Thu, 25 Jul 2024 01:12:21 -0700 Subject: [PATCH 047/186] Feat: eth_simulateV1 Request / Response types (#1042) * Feat: eth_simulateV1 Request / Response types * Update lib.rs * Update simulate.rs * fmt * Update simulate.rs * Update simulate.rs * Delete crates/rpc-types-trace/src/simulate.rs * Update lib.rs * Create simulate.rs * Update lib.rs * fmt * fmt * Update lib.rs * Update lib.rs * touchups * fix type --------- Co-authored-by: Matthias Seitz --- crates/rpc-types-eth/src/lib.rs | 2 + crates/rpc-types-eth/src/simulate.rs | 184 +++++++++++++++++++++++++++ 2 files changed, 186 insertions(+) create mode 100644 crates/rpc-types-eth/src/simulate.rs diff --git a/crates/rpc-types-eth/src/lib.rs b/crates/rpc-types-eth/src/lib.rs index 2219acba233..dd11ef33b68 100644 --- a/crates/rpc-types-eth/src/lib.rs +++ b/crates/rpc-types-eth/src/lib.rs @@ -49,3 +49,5 @@ pub use work::Work; /// This module provides implementations for EIP-4337. pub mod eip4337; + +pub mod simulate; diff --git a/crates/rpc-types-eth/src/simulate.rs b/crates/rpc-types-eth/src/simulate.rs new file mode 100644 index 00000000000..715c4a99dfd --- /dev/null +++ b/crates/rpc-types-eth/src/simulate.rs @@ -0,0 +1,184 @@ +//! 'eth_simulateV1' Request / Response types: + +use alloy_primitives::{Address, Bytes, Log, B256}; +use serde::{Deserialize, Serialize}; + +use crate::{state::StateOverride, BlockOverrides, TransactionRequest}; + +/// The maximum number of blocks that can be simulated in a single request, +pub const MAX_SIMULATE_BLOCKS: u64 = 256; + +/// Represents a batch of calls to be simulated sequentially within a block. +/// This struct includes block and state overrides as well as the transaction requests to be +/// executed. +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SimBlock { + /// Modifications to the default block characteristics. + pub block_overrides: BlockOverrides, + /// State modifications to apply before executing the transactions. + pub state_overrides: StateOverride, + /// A vector of transactions to be simulated. + pub calls: Vec, +} +/// Represents the result of simulating a block. +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SimulatedBlock { + /// The number of the block. + #[serde(with = "alloy_serde::quantity")] + pub number: u64, + /// The hash of the block. + pub hash: B256, + /// The timestamp of the block. + #[serde(with = "alloy_serde::quantity")] + pub timestamp: u64, + /// The gas limit of the block. + #[serde(with = "alloy_serde::quantity")] + pub gas_limit: u64, + /// The amount of gas used in the block. + #[serde(with = "alloy_serde::quantity")] + pub gas_used: u64, + /// The recipient of the block's fees. + pub fee_recipient: Address, + /// The base fee per gas unit for the block. + #[serde(with = "alloy_serde::quantity")] + pub base_fee_per_gas: u64, + /// The previous RANDAO value of the block. + pub prev_randao: B256, + /// A vector of results for each call in the block. + pub calls: Vec, +} +/// The response type for the eth_simulateV1 method. +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SimulateV1Response { + /// Simulated blocks vector. + pub simulated_blocks: Vec, +} +/// Captures the outcome of a transaction simulation. +/// It includes the return value, logs produced, gas used, and the status of the transaction. +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SimCallResult { + /// The raw bytes returned by the transaction. + pub return_value: Bytes, + /// Logs generated during the execution of the transaction. + #[serde(default)] + pub logs: Vec, + /// The amount of gas used by the transaction. + #[serde(with = "alloy_serde::quantity")] + pub gas_used: u64, + /// The final status of the transaction, typically indicating success or failure. + #[serde(with = "alloy_serde::quantity")] + pub status: u64, + /// Error in case the call failed + #[serde(default, skip_serializing_if = "Option::is_none")] + pub error: Option, +} + +/// Simulation options for executing multiple blocks and transactions. +/// This struct configures how simulations are executed, including whether to trace token transfers, +/// validate transaction sequences, and whether to return full transaction objects. +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SimulatePayload { + /// Array of block state calls to be executed at specific, optional block/state. + pub block_state_calls: Vec, + /// Flag to determine whether to trace ERC20/ERC721 token transfers within transactions. + #[serde(default)] + pub trace_transfers: bool, + /// Flag to enable or disable validation of the transaction sequence in the blocks. + #[serde(default)] + pub validation: bool, + /// Flag to decide if full transactions should be returned instead of just their hashes. + pub return_full_transactions: bool, +} + +/// The error response returned by the `eth_simulateV1` method. +#[derive(Clone, Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SimulateError { + /// Code error + /// -3200: Execution reverted + /// -32015: VM execution error + pub code: i32, + /// Message error + pub message: String, +} + +#[cfg(test)] +mod tests { + use super::*; + use alloy_primitives::{Address, TxKind}; + use serde_json::json; + + #[test] + fn test_eth_simulate_v1_account_not_precompile() { + let request_json = json!({ + "jsonrpc": "2.0", + "id": 1, + "method": "eth_simulateV1", + "params": [{ + "blockStateCalls": [ + { + "blockOverrides": {}, + "stateOverrides": { + "0xc000000000000000000000000000000000000000": { + "nonce": "0x5" + } + }, + "calls": [] + }, + { + "blockOverrides": {}, + "stateOverrides": { + "0xc000000000000000000000000000000000000000": { + "code": "0x600035600055" + } + }, + "calls": [ + { + "from": "0xc000000000000000000000000000000000000000", + "to": "0xc000000000000000000000000000000000000000", + "nonce": "0x0" + }, + { + "from": "0xc100000000000000000000000000000000000000", + "to": "0xc100000000000000000000000000000000000000", + "nonce": "0x5" + } + ] + } + ], + "traceTransfers": false, + "validation": true, + "returnFullTransactions": false + }, "latest"] + }); + + let sim_opts: SimulatePayload = + serde_json::from_value(request_json["params"][0].clone()).unwrap(); + + let address_1: Address = "0xc000000000000000000000000000000000000000".parse().unwrap(); + let address_2: Address = "0xc100000000000000000000000000000000000000".parse().unwrap(); + + assert!(sim_opts.validation); + assert_eq!(sim_opts.block_state_calls.len(), 2); + + let block_state_call_1 = &sim_opts.block_state_calls[0]; + assert!(block_state_call_1.state_overrides.contains_key(&address_1)); + assert_eq!(block_state_call_1.state_overrides.get(&address_1).unwrap().nonce.unwrap(), 5); + + let block_state_call_2 = &sim_opts.block_state_calls[1]; + assert!(block_state_call_2.state_overrides.contains_key(&address_1)); + + assert_eq!(block_state_call_2.calls.len(), 2); + assert_eq!(block_state_call_2.calls[0].from.unwrap(), address_1); + assert_eq!(block_state_call_2.calls[0].to.unwrap(), TxKind::Call(address_1)); + assert_eq!(block_state_call_2.calls[0].nonce.unwrap(), 0); + assert_eq!(block_state_call_2.calls[1].from.unwrap(), address_2); + assert_eq!(block_state_call_2.calls[1].to.unwrap(), TxKind::Call(address_2)); + assert_eq!(block_state_call_2.calls[1].nonce.unwrap(), 5); + } +} From 2ce8525d016f3fa9dc9c5a61afe44126a479243f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien?= <3535019+leruaa@users.noreply.github.com> Date: Thu, 25 Jul 2024 10:53:24 +0200 Subject: [PATCH 048/186] feat: use EncodableSignature for tx encoding (#1100) * feat: use EncodableSignature for tx encoding * feat: integrate EncodableSignature in alloy directly --- crates/consensus/src/encodable_signature.rs | 108 ++++++++++++++++++++ crates/consensus/src/lib.rs | 3 + crates/consensus/src/transaction/eip1559.rs | 12 ++- crates/consensus/src/transaction/eip2930.rs | 12 ++- crates/consensus/src/transaction/eip4844.rs | 12 ++- crates/consensus/src/transaction/eip7702.rs | 12 ++- crates/consensus/src/transaction/legacy.rs | 16 +-- crates/signer/src/lib.rs | 2 + 8 files changed, 158 insertions(+), 19 deletions(-) create mode 100644 crates/consensus/src/encodable_signature.rs diff --git a/crates/consensus/src/encodable_signature.rs b/crates/consensus/src/encodable_signature.rs new file mode 100644 index 00000000000..02d8a434421 --- /dev/null +++ b/crates/consensus/src/encodable_signature.rs @@ -0,0 +1,108 @@ +use alloy_primitives::{Parity, SignatureError, U256}; + +/// Helper trait used to streamline signatures encoding. +pub trait EncodableSignature: Sized { + /// Instantiate from v, r, s. + fn from_rs_and_parity, E: Into>( + r: U256, + s: U256, + parity: P, + ) -> Result; + + /// Returns the `r` component of this signature. + fn r(&self) -> U256; + + /// Returns the `s` component of this signature. + fn s(&self) -> U256; + + /// Returns the recovery ID as a `u8`. + fn v(&self) -> Parity; + + /// Sets the recovery ID by normalizing a `v` value. + fn with_parity>(self, parity: T) -> Self; + + /// Modifies the recovery ID by applying [EIP-155] to a `v` value. + /// + /// [EIP-155]: https://eips.ethereum.org/EIPS/eip-155 + #[inline] + fn with_chain_id(self, chain_id: u64) -> Self + where + Self: Copy, + { + self.with_parity(self.v().with_chain_id(chain_id)) + } + + /// Modifies the recovery ID by dropping any [EIP-155] v value, converting + /// to a simple parity bool. + fn with_parity_bool(self) -> Self + where + Self: Copy, + { + self.with_parity(self.v().to_parity_bool()) + } + + /// Decode an RLP-encoded VRS signature. + fn decode_rlp_vrs(buf: &mut &[u8]) -> Result { + use alloy_rlp::Decodable; + + let parity: Parity = Decodable::decode(buf)?; + let r = Decodable::decode(buf)?; + let s = Decodable::decode(buf)?; + + Self::from_rs_and_parity(r, s, parity) + .map_err(|_| alloy_rlp::Error::Custom("attempted to decode invalid field element")) + } + + /// Length of RLP RS field encoding + fn rlp_rs_len(&self) -> usize { + alloy_rlp::Encodable::length(&self.r()) + alloy_rlp::Encodable::length(&self.s()) + } + + /// Length of RLP V field encoding + fn rlp_vrs_len(&self) -> usize { + self.rlp_rs_len() + alloy_rlp::Encodable::length(&self.v()) + } + + /// Write R and S to an RLP buffer in progress. + fn write_rlp_rs(&self, out: &mut dyn alloy_rlp::BufMut) { + alloy_rlp::Encodable::encode(&self.r(), out); + alloy_rlp::Encodable::encode(&self.s(), out); + } + + /// Write the V to an RLP buffer without using EIP-155. + fn write_rlp_v(&self, out: &mut dyn alloy_rlp::BufMut) { + alloy_rlp::Encodable::encode(&self.v(), out); + } + + /// Write the VRS to the output. The V will always be 27 or 28. + fn write_rlp_vrs(&self, out: &mut dyn alloy_rlp::BufMut) { + self.write_rlp_v(out); + self.write_rlp_rs(out); + } +} + +impl EncodableSignature for alloy_primitives::Signature { + fn from_rs_and_parity, E: Into>( + r: U256, + s: U256, + parity: P, + ) -> Result { + Self::from_rs_and_parity(r, s, parity) + } + + fn r(&self) -> U256 { + self.r() + } + + fn s(&self) -> U256 { + self.s() + } + + fn v(&self) -> Parity { + self.v() + } + + fn with_parity>(self, parity: T) -> Self { + self.with_parity(parity) + } +} diff --git a/crates/consensus/src/lib.rs b/crates/consensus/src/lib.rs index 5cef218eab9..b1748bbde4c 100644 --- a/crates/consensus/src/lib.rs +++ b/crates/consensus/src/lib.rs @@ -15,6 +15,9 @@ pub use account::Account; pub mod constants; +mod encodable_signature; +pub use encodable_signature::EncodableSignature; + mod header; pub use header::{Header, EMPTY_OMMER_ROOT_HASH, EMPTY_ROOT_HASH}; diff --git a/crates/consensus/src/transaction/eip1559.rs b/crates/consensus/src/transaction/eip1559.rs index 3d09bc93a5b..219cf98c6fd 100644 --- a/crates/consensus/src/transaction/eip1559.rs +++ b/crates/consensus/src/transaction/eip1559.rs @@ -1,4 +1,4 @@ -use crate::{SignableTransaction, Signed, Transaction, TxType}; +use crate::{EncodableSignature, SignableTransaction, Signed, Transaction, TxType}; use alloy_eips::eip2930::AccessList; use alloy_primitives::{keccak256, Bytes, ChainId, Signature, TxKind, U256}; use alloy_rlp::{BufMut, Decodable, Encodable, Header}; @@ -153,7 +153,10 @@ impl TxEip1559 { /// /// If `with_header` is `true`, the payload length will include the RLP header length. /// If `with_header` is `false`, the payload length will not include the RLP header length. - pub fn encoded_len_with_signature(&self, signature: &Signature, with_header: bool) -> usize { + pub fn encoded_len_with_signature(&self, signature: &S, with_header: bool) -> usize + where + S: EncodableSignature, + { // this counts the tx fields and signature fields let payload_length = self.fields_len() + signature.rlp_vrs_len(); @@ -228,7 +231,10 @@ impl TxEip1559 { /// tx type byte or string header. /// /// This __does__ encode a list header and include a signature. - pub(crate) fn encode_with_signature_fields(&self, signature: &Signature, out: &mut dyn BufMut) { + pub fn encode_with_signature_fields(&self, signature: &S, out: &mut dyn BufMut) + where + S: EncodableSignature, + { let payload_length = self.fields_len() + signature.rlp_vrs_len(); let header = Header { list: true, payload_length }; header.encode(out); diff --git a/crates/consensus/src/transaction/eip2930.rs b/crates/consensus/src/transaction/eip2930.rs index 621dd15edad..ee0f0896323 100644 --- a/crates/consensus/src/transaction/eip2930.rs +++ b/crates/consensus/src/transaction/eip2930.rs @@ -1,4 +1,4 @@ -use crate::{SignableTransaction, Signed, Transaction, TxType}; +use crate::{EncodableSignature, SignableTransaction, Signed, Transaction, TxType}; use alloy_eips::eip2930::AccessList; use alloy_primitives::{keccak256, Bytes, ChainId, Signature, TxKind, U256}; use alloy_rlp::{length_of_length, BufMut, Decodable, Encodable, Header}; @@ -131,7 +131,10 @@ impl TxEip2930 { /// /// If `with_header` is `true`, the payload length will include the RLP header length. /// If `with_header` is `false`, the payload length will not include the RLP header length. - pub fn encoded_len_with_signature(&self, signature: &Signature, with_header: bool) -> usize { + pub fn encoded_len_with_signature(&self, signature: &S, with_header: bool) -> usize + where + S: EncodableSignature, + { // this counts the tx fields and signature fields let payload_length = self.fields_len() + signature.rlp_vrs_len(); @@ -176,7 +179,10 @@ impl TxEip2930 { /// tx type byte or string header. /// /// This __does__ encode a list header and include a signature. - pub(crate) fn encode_with_signature_fields(&self, signature: &Signature, out: &mut dyn BufMut) { + pub fn encode_with_signature_fields(&self, signature: &S, out: &mut dyn BufMut) + where + S: EncodableSignature, + { let payload_length = self.fields_len() + signature.rlp_vrs_len(); let header = Header { list: true, payload_length }; header.encode(out); diff --git a/crates/consensus/src/transaction/eip4844.rs b/crates/consensus/src/transaction/eip4844.rs index 4c00cbfc825..0b886fcfe19 100644 --- a/crates/consensus/src/transaction/eip4844.rs +++ b/crates/consensus/src/transaction/eip4844.rs @@ -1,4 +1,4 @@ -use crate::{SignableTransaction, Signed, Transaction, TxType}; +use crate::{EncodableSignature, SignableTransaction, Signed, Transaction, TxType}; use alloy_eips::{eip2930::AccessList, eip4844::DATA_GAS_PER_BLOB}; use alloy_primitives::{keccak256, Address, Bytes, ChainId, Signature, TxKind, B256, U256}; @@ -493,7 +493,10 @@ impl TxEip4844 { /// /// If `with_header` is `true`, the payload length will include the RLP header length. /// If `with_header` is `false`, the payload length will not include the RLP header length. - pub fn encoded_len_with_signature(&self, signature: &Signature, with_header: bool) -> usize { + pub fn encoded_len_with_signature(&self, signature: &S, with_header: bool) -> usize + where + S: EncodableSignature, + { // this counts the tx fields and signature fields let payload_length = self.fields_len() + signature.rlp_vrs_len(); @@ -538,7 +541,10 @@ impl TxEip4844 { /// tx type byte or string header. /// /// This __does__ encode a list header and include a signature. - pub(crate) fn encode_with_signature_fields(&self, signature: &Signature, out: &mut dyn BufMut) { + pub fn encode_with_signature_fields(&self, signature: &S, out: &mut dyn BufMut) + where + S: EncodableSignature, + { let payload_length = self.fields_len() + signature.rlp_vrs_len(); let header = Header { list: true, payload_length }; header.encode(out); diff --git a/crates/consensus/src/transaction/eip7702.rs b/crates/consensus/src/transaction/eip7702.rs index e852cee0ab0..6db47db3905 100644 --- a/crates/consensus/src/transaction/eip7702.rs +++ b/crates/consensus/src/transaction/eip7702.rs @@ -1,4 +1,4 @@ -use crate::{SignableTransaction, Signed, Transaction, TxType}; +use crate::{EncodableSignature, SignableTransaction, Signed, Transaction, TxType}; use alloy_eips::eip2930::AccessList; use alloy_primitives::{keccak256, Bytes, ChainId, Signature, TxKind, U256}; use alloy_rlp::{BufMut, Decodable, Encodable, Header}; @@ -161,7 +161,10 @@ impl TxEip7702 { /// /// If `with_header` is `true`, the payload length will include the RLP header length. /// If `with_header` is `false`, the payload length will not include the RLP header length. - pub fn encoded_len_with_signature(&self, signature: &Signature, with_header: bool) -> usize { + pub fn encoded_len_with_signature(&self, signature: &S, with_header: bool) -> usize + where + S: EncodableSignature, + { // this counts the tx fields and signature fields let payload_length = self.fields_len() + signature.rlp_vrs_len(); @@ -236,7 +239,10 @@ impl TxEip7702 { /// tx type byte or string header. /// /// This __does__ encode a list header and include a signature. - pub(crate) fn encode_with_signature_fields(&self, signature: &Signature, out: &mut dyn BufMut) { + pub fn encode_with_signature_fields(&self, signature: &S, out: &mut dyn BufMut) + where + S: EncodableSignature, + { let payload_length = self.fields_len() + signature.rlp_vrs_len(); let header = Header { list: true, payload_length }; header.encode(out); diff --git a/crates/consensus/src/transaction/legacy.rs b/crates/consensus/src/transaction/legacy.rs index 6b2fb66ff22..04733e405cc 100644 --- a/crates/consensus/src/transaction/legacy.rs +++ b/crates/consensus/src/transaction/legacy.rs @@ -1,4 +1,4 @@ -use crate::{SignableTransaction, Signed, Transaction}; +use crate::{EncodableSignature, SignableTransaction, Signed, Transaction}; use alloy_primitives::{keccak256, Bytes, ChainId, Signature, TxKind, U256}; use alloy_rlp::{length_of_length, BufMut, Decodable, Encodable, Header, Result}; use core::mem; @@ -104,11 +104,10 @@ impl TxLegacy { /// tx type byte or string header. /// /// This __does__ encode a list header and include a signature. - pub fn encode_with_signature_fields( - &self, - signature: &Signature, - out: &mut dyn alloy_rlp::BufMut, - ) { + pub fn encode_with_signature_fields(&self, signature: &S, out: &mut dyn alloy_rlp::BufMut) + where + S: EncodableSignature, + { let payload_length = self.fields_len() + signature.rlp_vrs_len(); let header = Header { list: true, payload_length }; header.encode(out); @@ -118,7 +117,10 @@ impl TxLegacy { /// Returns what the encoded length should be, if the transaction were RLP encoded with the /// given signature. - pub fn encoded_len_with_signature(&self, signature: &Signature) -> usize { + pub fn encoded_len_with_signature(&self, signature: &S) -> usize + where + S: EncodableSignature, + { let payload_length = self.fields_len() + signature.rlp_vrs_len(); Header { list: true, payload_length }.length() + payload_length } diff --git a/crates/signer/src/lib.rs b/crates/signer/src/lib.rs index 43ecb3017d9..3f5e45ee864 100644 --- a/crates/signer/src/lib.rs +++ b/crates/signer/src/lib.rs @@ -27,6 +27,8 @@ macro_rules! sign_transaction_with_chain_id { // sign: lazy Signature, // ) ($signer:expr, $tx:expr, $sign:expr) => {{ + use alloy_consensus::EncodableSignature; + if let Some(chain_id) = $signer.chain_id() { if !$tx.set_chain_id_checked(chain_id) { return Err(alloy_signer::Error::TransactionChainIdMismatch { From a537f8b22bc0d29cff79b036f74baf17912869e2 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Thu, 25 Jul 2024 21:27:19 +0200 Subject: [PATCH 049/186] chore: allow override all group (#1104) --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 9f17dd07bd8..5eb39ab9660 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ unnameable-types = "warn" all = "warn" [workspace.lints.clippy] -all = "warn" +all = { level = "warn", priority = -1 } missing-const-for-fn = "warn" use-self = "warn" option-if-let-else = "warn" From 2de4e23e36a42b2445f8d0879eb7149e997489fe Mon Sep 17 00:00:00 2001 From: Oliver Date: Thu, 25 Jul 2024 23:02:44 +0200 Subject: [PATCH 050/186] fix: correctly trim eip7251 bytecode (#1105) --- crates/eips/src/eip7251.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/eips/src/eip7251.rs b/crates/eips/src/eip7251.rs index 23406b59efb..a5ffc0b19f9 100644 --- a/crates/eips/src/eip7251.rs +++ b/crates/eips/src/eip7251.rs @@ -11,7 +11,7 @@ pub const CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS: Address = address!("00b42dbF2194e931E80326D950320f7d9Dbeac02"); /// The code for the EIP-7251 consolidation requests contract. -pub static CONSOLIDATION_REQUEST_PREDEPLOY_CODE: Bytes = bytes!("0f5f395ff33373fffffffffffffffffffffffffffffffffffffffe146098573615156028575f545f5260205ff35b36606014156101445760115f54600182026001905f5b5f82111560595781019083028483029004916001019190603e565b90939004341061014457600154600101600155600354806004026004013381556001015f35815560010160203581556001016040359055600101600355005b6003546002548082038060011160ac575060015b5f5b81811460f15780607402838201600402600401805490600101805490600101805490600101549260601b84529083601401528260340152906054015260010160ae565b9101809214610103579060025561010e565b90505f6002555f6003555b5f548061049d141561011d57505f5b6001546001828201116101325750505f610138565b01600190035b5f555f6001556074025ff35b5f5ffd"); +pub static CONSOLIDATION_REQUEST_PREDEPLOY_CODE: Bytes = bytes!("3373fffffffffffffffffffffffffffffffffffffffe146098573615156028575f545f5260205ff35b36606014156101445760115f54600182026001905f5b5f82111560595781019083028483029004916001019190603e565b90939004341061014457600154600101600155600354806004026004013381556001015f35815560010160203581556001016040359055600101600355005b6003546002548082038060011160ac575060015b5f5b81811460f15780607402838201600402600401805490600101805490600101805490600101549260601b84529083601401528260340152906054015260010160ae565b9101809214610103579060025561010e565b90505f6002555f6003555b5f548061049d141561011d57505f5b6001546001828201116101325750505f610138565b01600190035b5f555f6001556074025ff35b5f5ffd"); /// The [EIP-7685](https://eips.ethereum.org/EIPS/eip-7685) request type for consolidation requests. pub const CONSOLIDATION_REQUEST_TYPE: u8 = 0x02; From 4ba532373eb085a5426d2de8c71c0b7273e9b62c Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Fri, 26 Jul 2024 14:41:18 +0800 Subject: [PATCH 051/186] refactor: add network-primitives (#1101) * refactor: add network-primitives * fix tests * fix docs * add re-exports * Block --- Cargo.toml | 1 + crates/contract/Cargo.toml | 1 + crates/contract/src/call.rs | 3 +- crates/network-primitives/Cargo.toml | 28 ++ crates/network-primitives/README.md | 3 + crates/network-primitives/src/block.rs | 258 ++++++++++++++ crates/network-primitives/src/lib.rs | 13 + crates/network-primitives/src/traits.rs | 91 +++++ crates/network/Cargo.toml | 1 + crates/network/src/any/mod.rs | 48 +-- crates/network/src/ethereum/mod.rs | 48 +-- crates/network/src/lib.rs | 60 +--- crates/provider/Cargo.toml | 1 + crates/provider/src/heart.rs | 4 +- crates/provider/src/provider/trait.rs | 7 +- crates/rpc-types-eth/Cargo.toml | 2 + crates/rpc-types-eth/src/block.rs | 328 +----------------- crates/rpc-types-eth/src/lib.rs | 4 + crates/rpc-types-eth/src/transaction/mod.rs | 26 ++ .../rpc-types-eth/src/transaction/receipt.rs | 21 +- 20 files changed, 461 insertions(+), 487 deletions(-) create mode 100644 crates/network-primitives/Cargo.toml create mode 100644 crates/network-primitives/README.md create mode 100644 crates/network-primitives/src/block.rs create mode 100644 crates/network-primitives/src/lib.rs create mode 100644 crates/network-primitives/src/traits.rs diff --git a/Cargo.toml b/Cargo.toml index 5eb39ab9660..590aa9fc7a8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,6 +42,7 @@ alloy-eip7547 = { version = "0.2", path = "crates/eip7547", default-features = f alloy-genesis = { version = "0.2", path = "crates/genesis", default-features = false } alloy-json-rpc = { version = "0.2", path = "crates/json-rpc", default-features = false } alloy-network = { version = "0.2", path = "crates/network", default-features = false } +alloy-network-primitives = { version = "0.2", path = "crates/network-primitives", default-features = false } alloy-node-bindings = { version = "0.2", path = "crates/node-bindings", default-features = false } alloy-provider = { version = "0.2", path = "crates/provider", default-features = false } alloy-pubsub = { version = "0.2", path = "crates/pubsub", default-features = false } diff --git a/crates/contract/Cargo.toml b/crates/contract/Cargo.toml index 67610f3688a..b1862a2b99e 100644 --- a/crates/contract/Cargo.toml +++ b/crates/contract/Cargo.toml @@ -20,6 +20,7 @@ workspace = true [dependencies] alloy-network.workspace = true +alloy-network-primitives.workspace = true alloy-provider.workspace = true alloy-rpc-types-eth.workspace = true alloy-transport.workspace = true diff --git a/crates/contract/src/call.rs b/crates/contract/src/call.rs index 77ba97815a2..d9aaf5279ce 100644 --- a/crates/contract/src/call.rs +++ b/crates/contract/src/call.rs @@ -1,7 +1,8 @@ use crate::{CallDecoder, Error, EthCall, Result}; use alloy_dyn_abi::{DynSolValue, JsonAbiExt}; use alloy_json_abi::Function; -use alloy_network::{Ethereum, Network, ReceiptResponse, TransactionBuilder}; +use alloy_network::{Ethereum, Network, TransactionBuilder}; +use alloy_network_primitives::ReceiptResponse; use alloy_primitives::{Address, Bytes, ChainId, TxKind, U256}; use alloy_provider::{PendingTransactionBuilder, Provider}; use alloy_rpc_types_eth::{state::StateOverride, AccessList, BlobTransactionSidecar, BlockId}; diff --git a/crates/network-primitives/Cargo.toml b/crates/network-primitives/Cargo.toml new file mode 100644 index 00000000000..a56fb3e6239 --- /dev/null +++ b/crates/network-primitives/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "alloy-network-primitives" +description = "Primitive types for Alloy network abstraction" + +version.workspace = true +edition.workspace = true +rust-version.workspace = true +authors.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true +exclude.workspace = true + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true + +[dependencies] +alloy-primitives.workspace = true +alloy-serde.workspace = true + +serde.workspace = true + +[dev-dependencies] +rand.workspace = true diff --git a/crates/network-primitives/README.md b/crates/network-primitives/README.md new file mode 100644 index 00000000000..d5ef0b8d631 --- /dev/null +++ b/crates/network-primitives/README.md @@ -0,0 +1,3 @@ +# alloy-network-primitives + +Primitive types for Alloy network abstraction. \ No newline at end of file diff --git a/crates/network-primitives/src/block.rs b/crates/network-primitives/src/block.rs new file mode 100644 index 00000000000..1ec52f338ba --- /dev/null +++ b/crates/network-primitives/src/block.rs @@ -0,0 +1,258 @@ +use alloy_primitives::B256; +use serde::{Deserialize, Serialize}; + +use crate::TransactionResponse; + +/// Block Transactions depending on the boolean attribute of `eth_getBlockBy*`, +/// or if used by `eth_getUncle*` +#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[serde(untagged)] +pub enum BlockTransactions { + /// Full transactions + Full(Vec), + /// Only hashes + Hashes(Vec), + /// Special case for uncle response. + Uncle, +} + +impl Default for BlockTransactions { + fn default() -> Self { + Self::Hashes(Vec::default()) + } +} + +impl BlockTransactions { + /// Check if the enum variant is used for hashes. + #[inline] + pub const fn is_hashes(&self) -> bool { + matches!(self, Self::Hashes(_)) + } + + /// Fallibly cast to a slice of hashes. + pub fn as_hashes(&self) -> Option<&[B256]> { + match self { + Self::Hashes(hashes) => Some(hashes), + _ => None, + } + } + + /// Returns true if the enum variant is used for full transactions. + #[inline] + pub const fn is_full(&self) -> bool { + matches!(self, Self::Full(_)) + } + + /// Fallibly cast to a slice of transactions. + /// + /// Returns `None` if the enum variant is not `Full`. + pub fn as_transactions(&self) -> Option<&[T]> { + match self { + Self::Full(txs) => Some(txs), + _ => None, + } + } + + /// Returns true if the enum variant is used for an uncle response. + #[inline] + pub const fn is_uncle(&self) -> bool { + matches!(self, Self::Uncle) + } + + /// Returns an iterator over the transactions (if any). This will be empty + /// if the block is an uncle or if the transaction list contains only + /// hashes. + #[doc(alias = "transactions")] + pub fn txns(&self) -> impl Iterator { + self.as_transactions().map(|txs| txs.iter()).unwrap_or_else(|| [].iter()) + } + + /// Returns an iterator over the transactions (if any). This will be empty if the block is not + /// full. + pub fn into_transactions(self) -> std::vec::IntoIter { + match self { + Self::Full(txs) => txs.into_iter(), + _ => std::vec::IntoIter::default(), + } + } + + /// Returns an instance of BlockTransactions with the Uncle special case. + #[inline] + pub const fn uncle() -> Self { + Self::Uncle + } + + /// Returns the number of transactions. + #[inline] + pub fn len(&self) -> usize { + match self { + Self::Hashes(h) => h.len(), + Self::Full(f) => f.len(), + Self::Uncle => 0, + } + } + + /// Whether the block has no transactions. + #[inline] + pub fn is_empty(&self) -> bool { + self.len() == 0 + } +} + +impl BlockTransactions { + /// Converts `self` into `Hashes`. + #[inline] + pub fn convert_to_hashes(&mut self) { + if !self.is_hashes() { + *self = Self::Hashes(self.hashes().collect()); + } + } + + /// Converts `self` into `Hashes`. + #[inline] + pub fn into_hashes(mut self) -> Self { + self.convert_to_hashes(); + self + } + + /// Returns an iterator over the transaction hashes. + #[deprecated = "use `hashes` instead"] + #[inline] + pub fn iter(&self) -> BlockTransactionHashes<'_, T> { + self.hashes() + } + + /// Returns an iterator over references to the transaction hashes. + #[inline] + pub fn hashes(&self) -> BlockTransactionHashes<'_, T> { + BlockTransactionHashes::new(self) + } +} + +impl From> for BlockTransactions { + fn from(hashes: Vec) -> Self { + Self::Hashes(hashes) + } +} + +impl From> for BlockTransactions { + fn from(transactions: Vec) -> Self { + Self::Full(transactions) + } +} + +/// An iterator over the transaction hashes of a block. +/// +/// See [`BlockTransactions::hashes`]. +#[derive(Clone, Debug)] +pub struct BlockTransactionHashes<'a, T>(BlockTransactionHashesInner<'a, T>); + +#[derive(Clone, Debug)] +enum BlockTransactionHashesInner<'a, T> { + Hashes(std::slice::Iter<'a, B256>), + Full(std::slice::Iter<'a, T>), + Uncle, +} + +impl<'a, T> BlockTransactionHashes<'a, T> { + #[inline] + fn new(txs: &'a BlockTransactions) -> Self { + Self(match txs { + BlockTransactions::Hashes(txs) => BlockTransactionHashesInner::Hashes(txs.iter()), + BlockTransactions::Full(txs) => BlockTransactionHashesInner::Full(txs.iter()), + BlockTransactions::Uncle => BlockTransactionHashesInner::Uncle, + }) + } +} + +impl<'a, T: TransactionResponse> Iterator for BlockTransactionHashes<'a, T> { + type Item = B256; + + #[inline] + fn next(&mut self) -> Option { + match &mut self.0 { + BlockTransactionHashesInner::Hashes(txs) => txs.next().copied(), + BlockTransactionHashesInner::Full(txs) => txs.next().map(|tx| tx.tx_hash()), + BlockTransactionHashesInner::Uncle => None, + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + match &self.0 { + BlockTransactionHashesInner::Full(txs) => txs.size_hint(), + BlockTransactionHashesInner::Hashes(txs) => txs.size_hint(), + BlockTransactionHashesInner::Uncle => (0, Some(0)), + } + } +} + +impl ExactSizeIterator for BlockTransactionHashes<'_, T> { + #[inline] + fn len(&self) -> usize { + match &self.0 { + BlockTransactionHashesInner::Full(txs) => txs.len(), + BlockTransactionHashesInner::Hashes(txs) => txs.len(), + BlockTransactionHashesInner::Uncle => 0, + } + } +} + +impl DoubleEndedIterator for BlockTransactionHashes<'_, T> { + #[inline] + fn next_back(&mut self) -> Option { + match &mut self.0 { + BlockTransactionHashesInner::Full(txs) => txs.next_back().map(|tx| tx.tx_hash()), + BlockTransactionHashesInner::Hashes(txs) => txs.next_back().copied(), + BlockTransactionHashesInner::Uncle => None, + } + } +} + +impl<'a, T: TransactionResponse> std::iter::FusedIterator for BlockTransactionHashes<'a, T> {} + +/// Determines how the `transactions` field of block should be filled. +/// +/// This essentially represents the `full:bool` argument in RPC calls that determine whether the +/// response should include full transaction objects or just the hashes. +#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)] +pub enum BlockTransactionsKind { + /// Only include hashes: [BlockTransactions::Hashes] + #[default] + Hashes, + /// Include full transaction objects: [BlockTransactions::Full] + Full, +} + +impl From for BlockTransactionsKind { + fn from(is_full: bool) -> Self { + if is_full { + Self::Full + } else { + Self::Hashes + } + } +} + +impl From for bool { + fn from(kind: BlockTransactionsKind) -> Self { + match kind { + BlockTransactionsKind::Full => true, + BlockTransactionsKind::Hashes => false, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_full_conversion() { + let full = true; + assert_eq!(BlockTransactionsKind::Full, full.into()); + + let full = false; + assert_eq!(BlockTransactionsKind::Hashes, full.into()); + } +} diff --git a/crates/network-primitives/src/lib.rs b/crates/network-primitives/src/lib.rs new file mode 100644 index 00000000000..42f43f134ef --- /dev/null +++ b/crates/network-primitives/src/lib.rs @@ -0,0 +1,13 @@ +#![doc = include_str!("../README.md")] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/alloy-rs/core/main/assets/alloy.jpg", + html_favicon_url = "https://raw.githubusercontent.com/alloy-rs/core/main/assets/favicon.ico" +)] +#![cfg_attr(not(test), warn(unused_crate_dependencies))] +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] + +mod traits; +pub use traits::{ReceiptResponse, TransactionResponse}; + +mod block; +pub use block::{BlockTransactionHashes, BlockTransactions, BlockTransactionsKind}; diff --git a/crates/network-primitives/src/traits.rs b/crates/network-primitives/src/traits.rs new file mode 100644 index 00000000000..9580f19b584 --- /dev/null +++ b/crates/network-primitives/src/traits.rs @@ -0,0 +1,91 @@ +use alloy_primitives::{Address, BlockHash, Bytes, TxHash, U256}; +use alloy_serde::WithOtherFields; + +/// Receipt JSON-RPC response. +pub trait ReceiptResponse { + /// Address of the created contract, or `None` if the transaction was not a deployment. + fn contract_address(&self) -> Option
; + + /// Status of the transaction. + /// + /// ## Note + /// + /// Caution must be taken when using this method for deep-historical + /// receipts, as it may not accurately reflect the status of the + /// transaction. The transaction status is not knowable from the receipt + /// for transactions before [EIP-658]. + fn status(&self) -> bool; + + /// Hash of the block this transaction was included within. + fn block_hash(&self) -> Option; + + /// Number of the block this transaction was included within. + fn block_number(&self) -> Option; +} + +/// Transaction JSON-RPC response. +pub trait TransactionResponse { + /// Hash of the transaction + #[doc(alias = "transaction_hash")] + fn tx_hash(&self) -> TxHash; + + /// Sender of the transaction + fn from(&self) -> Address; + + /// Recipient of the transaction + fn to(&self) -> Option
; + + /// Transferred value + fn value(&self) -> U256; + + /// Gas limit + fn gas(&self) -> u128; + + /// Input data + #[doc(alias = "calldata")] + fn input(&self) -> &Bytes; +} + +impl TransactionResponse for WithOtherFields { + fn tx_hash(&self) -> TxHash { + self.inner.tx_hash() + } + + fn from(&self) -> Address { + self.inner.from() + } + + fn to(&self) -> Option
{ + self.inner.to() + } + + fn value(&self) -> U256 { + self.inner.value() + } + + fn gas(&self) -> u128 { + self.inner.gas() + } + + fn input(&self) -> &Bytes { + self.inner.input() + } +} + +impl ReceiptResponse for WithOtherFields { + fn contract_address(&self) -> Option
{ + self.inner.contract_address() + } + + fn status(&self) -> bool { + self.inner.status() + } + + fn block_hash(&self) -> Option { + self.inner.block_hash() + } + + fn block_number(&self) -> Option { + self.inner.block_number() + } +} diff --git a/crates/network/Cargo.toml b/crates/network/Cargo.toml index c84e8f6a706..9eda78c2426 100644 --- a/crates/network/Cargo.toml +++ b/crates/network/Cargo.toml @@ -22,6 +22,7 @@ workspace = true alloy-consensus = { workspace = true, features = ["std"] } alloy-eips = { workspace = true, features = ["serde"] } alloy-json-rpc.workspace = true +alloy-network-primitives.workspace = true alloy-primitives.workspace = true alloy-rpc-types-eth.workspace = true alloy-signer.workspace = true diff --git a/crates/network/src/any/mod.rs b/crates/network/src/any/mod.rs index 2acb0a1a5a1..8103b562ca2 100644 --- a/crates/network/src/any/mod.rs +++ b/crates/network/src/any/mod.rs @@ -1,7 +1,6 @@ -use crate::{Network, ReceiptResponse, TransactionResponse}; +use crate::Network; use alloy_consensus::TxType; use alloy_eips::eip2718::Eip2718Error; -use alloy_primitives::Bytes; use alloy_rpc_types_eth::{AnyTransactionReceipt, Header, Transaction, TransactionRequest}; use alloy_serde::WithOtherFields; use core::fmt; @@ -76,48 +75,3 @@ impl Network for AnyNetwork { type HeaderResponse = WithOtherFields
; } - -impl ReceiptResponse for AnyTransactionReceipt { - fn contract_address(&self) -> Option { - self.contract_address - } - - fn status(&self) -> bool { - self.inner.inner.status() - } - - fn block_hash(&self) -> Option { - self.inner.block_hash - } - - fn block_number(&self) -> Option { - self.inner.block_number - } -} - -impl TransactionResponse for WithOtherFields { - #[doc(alias = "transaction_hash")] - fn tx_hash(&self) -> alloy_primitives::B256 { - self.hash - } - - fn from(&self) -> alloy_primitives::Address { - self.from - } - - fn to(&self) -> Option { - self.to - } - - fn value(&self) -> alloy_primitives::U256 { - self.value - } - - fn gas(&self) -> u128 { - self.gas - } - - fn input(&self) -> &Bytes { - &self.input - } -} diff --git a/crates/network/src/ethereum/mod.rs b/crates/network/src/ethereum/mod.rs index 68729e3f0f9..0d2266874e4 100644 --- a/crates/network/src/ethereum/mod.rs +++ b/crates/network/src/ethereum/mod.rs @@ -1,5 +1,4 @@ -use crate::{Network, ReceiptResponse, TransactionResponse}; -use alloy_primitives::Bytes; +use crate::Network; mod builder; @@ -31,48 +30,3 @@ impl Network for Ethereum { type HeaderResponse = alloy_rpc_types_eth::Header; } - -impl ReceiptResponse for alloy_rpc_types_eth::TransactionReceipt { - fn contract_address(&self) -> Option { - self.contract_address - } - - fn status(&self) -> bool { - self.inner.status() - } - - fn block_hash(&self) -> Option { - self.block_hash - } - - fn block_number(&self) -> Option { - self.block_number - } -} - -impl TransactionResponse for alloy_rpc_types_eth::Transaction { - #[doc(alias = "transaction_hash")] - fn tx_hash(&self) -> alloy_primitives::B256 { - self.hash - } - - fn from(&self) -> alloy_primitives::Address { - self.from - } - - fn to(&self) -> Option { - self.to - } - - fn value(&self) -> alloy_primitives::U256 { - self.value - } - - fn gas(&self) -> u128 { - self.gas - } - - fn input(&self) -> &Bytes { - &self.input - } -} diff --git a/crates/network/src/lib.rs b/crates/network/src/lib.rs index 54431385f32..0719e452c57 100644 --- a/crates/network/src/lib.rs +++ b/crates/network/src/lib.rs @@ -9,7 +9,6 @@ use alloy_consensus::TxReceipt; use alloy_eips::eip2718::{Eip2718Envelope, Eip2718Error}; use alloy_json_rpc::RpcObject; -use alloy_primitives::{Address, BlockHash, Bytes, TxHash, U256}; use core::fmt::{Debug, Display}; mod transaction; @@ -25,64 +24,7 @@ mod any; pub use any::{AnyNetwork, AnyTxType}; pub use alloy_eips::eip2718; - -/// A receipt response. -/// -/// This is distinct from [`TxReceipt`], since this is for JSON-RPC receipts. -/// -/// [`TxReceipt`]: alloy_consensus::TxReceipt -pub trait ReceiptResponse { - /// Address of the created contract, or `None` if the transaction was not a deployment. - fn contract_address(&self) -> Option
; - - /// Status of the transaction. - /// - /// ## Note - /// - /// Caution must be taken when using this method for deep-historical - /// receipts, as it may not accurately reflect the status of the - /// transaction. The transaction status is not knowable from the receipt - /// for transactions before [EIP-658]. - /// - /// This can be handled using [`TxReceipt::status_or_post_state`]. - /// - /// [EIP-658]: https://eips.ethereum.org/EIPS/eip-658 - /// [`TxReceipt::status_or_post_state`]: alloy_consensus::TxReceipt::status_or_post_state - fn status(&self) -> bool; - - /// Hash of the block this transaction was included within. - fn block_hash(&self) -> Option; - - /// Number of the block this transaction was included within. - fn block_number(&self) -> Option; -} - -/// Transaction Response -/// -/// This is distinct from [`Transaction`], since this is a JSON-RPC response. -/// -/// [`Transaction`]: alloy_consensus::Transaction -pub trait TransactionResponse { - /// Hash of the transaction - #[doc(alias = "transaction_hash")] - fn tx_hash(&self) -> TxHash; - - /// Sender of the transaction - fn from(&self) -> Address; - - /// Recipient of the transaction - fn to(&self) -> Option
; - - /// Transferred value - fn value(&self) -> U256; - - /// Gas limit - fn gas(&self) -> u128; - - /// Input data - #[doc(alias = "calldata")] - fn input(&self) -> &Bytes; -} +pub use alloy_network_primitives::{ReceiptResponse, TransactionResponse}; /// Captures type info for network-specific RPC requests/responses. /// diff --git a/crates/provider/Cargo.toml b/crates/provider/Cargo.toml index 3fda009b291..d7b692c83e2 100644 --- a/crates/provider/Cargo.toml +++ b/crates/provider/Cargo.toml @@ -23,6 +23,7 @@ alloy-eips.workspace = true alloy-consensus.workspace = true alloy-json-rpc.workspace = true alloy-network.workspace = true +alloy-network-primitives.workspace = true alloy-node-bindings = { workspace = true, optional = true } alloy-signer-local = { workspace = true, optional = true } alloy-rpc-client.workspace = true diff --git a/crates/provider/src/heart.rs b/crates/provider/src/heart.rs index db7d4b7af0c..58de345c6a2 100644 --- a/crates/provider/src/heart.rs +++ b/crates/provider/src/heart.rs @@ -555,13 +555,13 @@ impl Heartbeat { self.past_blocks.retain(|(h, _)| h < block_height); } } - self.past_blocks.push_back((*block_height, block.transactions.hashes().copied().collect())); + self.past_blocks.push_back((*block_height, block.transactions.hashes().collect())); // Check if we are watching for any of the transactions in this block. let to_check: Vec<_> = block .transactions .hashes() - .filter_map(|tx_hash| self.unconfirmed.remove(tx_hash)) + .filter_map(|tx_hash| self.unconfirmed.remove(&tx_hash)) .collect(); for mut watcher in to_check { // If `confirmations` is not more than 1 we can notify the watcher immediately. diff --git a/crates/provider/src/provider/trait.rs b/crates/provider/src/provider/trait.rs index 7d4cc1f889e..6af73c6744b 100644 --- a/crates/provider/src/provider/trait.rs +++ b/crates/provider/src/provider/trait.rs @@ -7,15 +7,16 @@ use crate::{ }; use alloy_eips::eip2718::Encodable2718; use alloy_json_rpc::{RpcError, RpcParam, RpcReturn}; -use alloy_network::{Ethereum, Network, ReceiptResponse as _}; +use alloy_network::{Ethereum, Network}; +use alloy_network_primitives::{BlockTransactionsKind, ReceiptResponse}; use alloy_primitives::{ hex, Address, BlockHash, BlockNumber, Bytes, StorageKey, StorageValue, TxHash, B256, U128, U256, U64, }; use alloy_rpc_client::{ClientRef, PollerBuilder, RpcCall, WeakClient}; use alloy_rpc_types_eth::{ - AccessListWithGasUsed, Block, BlockId, BlockNumberOrTag, BlockTransactionsKind, - EIP1186AccountProofResponse, FeeHistory, Filter, FilterChanges, Log, SyncStatus, + AccessListWithGasUsed, Block, BlockId, BlockNumberOrTag, EIP1186AccountProofResponse, + FeeHistory, Filter, FilterChanges, Log, SyncStatus, }; use alloy_transport::{BoxTransport, Transport, TransportErrorKind, TransportResult}; use serde_json::value::RawValue; diff --git a/crates/rpc-types-eth/Cargo.toml b/crates/rpc-types-eth/Cargo.toml index e1c998b73e0..60d2bc135ab 100644 --- a/crates/rpc-types-eth/Cargo.toml +++ b/crates/rpc-types-eth/Cargo.toml @@ -26,6 +26,8 @@ alloy-serde.workspace = true alloy-consensus = { workspace = true, features = ["std", "serde"] } alloy-eips = { workspace = true, features = ["std", "serde"] } +alloy-network-primitives.workspace = true + itertools.workspace = true serde = { workspace = true, features = ["derive"] } serde_json.workspace = true diff --git a/crates/rpc-types-eth/src/block.rs b/crates/rpc-types-eth/src/block.rs index 3a549f55c82..1622b3c74f0 100644 --- a/crates/rpc-types-eth/src/block.rs +++ b/crates/rpc-types-eth/src/block.rs @@ -1,6 +1,7 @@ //! Block RPC types. use crate::{ConversionError, Transaction, Withdrawal}; +use alloy_network_primitives::BlockTransactions; use alloy_primitives::{Address, BlockHash, Bloom, Bytes, B256, B64, U256}; use alloy_serde::OtherFields; use serde::{ser::Error, Deserialize, Serialize, Serializer}; @@ -204,324 +205,6 @@ impl TryFrom
for alloy_consensus::Header { } } -/// Block Transactions depending on the boolean attribute of `eth_getBlockBy*`, -/// or if used by `eth_getUncle*` -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[serde(untagged)] -pub enum BlockTransactions { - /// Full transactions - Full(Vec), - /// Only hashes - Hashes(Vec), - /// Special case for uncle response. - Uncle, -} - -impl Default for BlockTransactions { - fn default() -> Self { - Self::Hashes(Vec::default()) - } -} - -impl BlockTransactions { - /// Check if the enum variant is used for hashes. - #[inline] - pub const fn is_hashes(&self) -> bool { - matches!(self, Self::Hashes(_)) - } - - /// Fallibly cast to a slice of hashes. - pub fn as_hashes(&self) -> Option<&[B256]> { - match self { - Self::Hashes(hashes) => Some(hashes), - _ => None, - } - } - - /// Returns true if the enum variant is used for full transactions. - #[inline] - pub const fn is_full(&self) -> bool { - matches!(self, Self::Full(_)) - } - - /// Fallibly cast to a slice of transactions. - /// - /// Returns `None` if the enum variant is not `Full`. - pub fn as_transactions(&self) -> Option<&[T]> { - match self { - Self::Full(txs) => Some(txs), - _ => None, - } - } - - /// Returns true if the enum variant is used for an uncle response. - #[inline] - pub const fn is_uncle(&self) -> bool { - matches!(self, Self::Uncle) - } - - /// Returns an iterator over the transactions (if any). This will be empty - /// if the block is an uncle or if the transaction list contains only - /// hashes. - #[doc(alias = "transactions")] - pub fn txns(&self) -> impl Iterator { - self.as_transactions().map(|txs| txs.iter()).unwrap_or_else(|| [].iter()) - } - - /// Returns an iterator over the transactions (if any). This will be empty if the block is not - /// full. - pub fn into_transactions(self) -> std::vec::IntoIter { - match self { - Self::Full(txs) => txs.into_iter(), - _ => std::vec::IntoIter::default(), - } - } - - /// Returns an instance of BlockTransactions with the Uncle special case. - #[inline] - pub const fn uncle() -> Self { - Self::Uncle - } - - /// Returns the number of transactions. - #[inline] - pub fn len(&self) -> usize { - match self { - Self::Hashes(h) => h.len(), - Self::Full(f) => f.len(), - Self::Uncle => 0, - } - } - - /// Whether the block has no transactions. - #[inline] - pub fn is_empty(&self) -> bool { - self.len() == 0 - } -} - -impl BlockTransactions { - /// Converts `self` into `Hashes`. - #[inline] - pub fn convert_to_hashes(&mut self) { - if !self.is_hashes() { - *self = Self::Hashes(self.hashes().copied().collect()); - } - } - - /// Converts `self` into `Hashes`. - #[inline] - pub fn into_hashes(mut self) -> Self { - self.convert_to_hashes(); - self - } - - /// Returns an iterator over the transaction hashes. - #[deprecated = "use `hashes` instead"] - #[inline] - pub fn iter(&self) -> BlockTransactionHashes<'_, Transaction> { - self.hashes() - } - - /// Returns an iterator over references to the transaction hashes. - #[inline] - pub fn hashes(&self) -> BlockTransactionHashes<'_, Transaction> { - BlockTransactionHashes::new(self) - } - - /// Returns an iterator over mutable references to the transaction hashes. - #[inline] - pub fn hashes_mut(&mut self) -> BlockTransactionHashesMut<'_, Transaction> { - BlockTransactionHashesMut::new(self) - } -} - -impl From> for BlockTransactions { - fn from(hashes: Vec) -> Self { - Self::Hashes(hashes) - } -} - -impl From> for BlockTransactions { - fn from(transactions: Vec) -> Self { - Self::Full(transactions) - } -} - -/// An iterator over the transaction hashes of a block. -/// -/// See [`BlockTransactions::hashes`]. -#[derive(Clone, Debug)] -pub struct BlockTransactionHashes<'a, T>(BlockTransactionHashesInner<'a, T>); - -#[derive(Clone, Debug)] -enum BlockTransactionHashesInner<'a, T = Transaction> { - Hashes(std::slice::Iter<'a, B256>), - Full(std::slice::Iter<'a, T>), - Uncle, -} - -impl<'a, T> BlockTransactionHashes<'a, T> { - #[inline] - fn new(txs: &'a BlockTransactions) -> Self { - Self(match txs { - BlockTransactions::Hashes(txs) => BlockTransactionHashesInner::Hashes(txs.iter()), - BlockTransactions::Full(txs) => BlockTransactionHashesInner::Full(txs.iter()), - BlockTransactions::Uncle => BlockTransactionHashesInner::Uncle, - }) - } -} - -impl<'a> Iterator for BlockTransactionHashes<'a, Transaction> { - type Item = &'a B256; - - #[inline] - fn next(&mut self) -> Option { - match &mut self.0 { - BlockTransactionHashesInner::Hashes(txs) => txs.next(), - BlockTransactionHashesInner::Full(txs) => txs.next().map(|tx| &tx.hash), - BlockTransactionHashesInner::Uncle => None, - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - match &self.0 { - BlockTransactionHashesInner::Full(txs) => txs.size_hint(), - BlockTransactionHashesInner::Hashes(txs) => txs.size_hint(), - BlockTransactionHashesInner::Uncle => (0, Some(0)), - } - } -} - -impl ExactSizeIterator for BlockTransactionHashes<'_, Transaction> { - #[inline] - fn len(&self) -> usize { - match &self.0 { - BlockTransactionHashesInner::Full(txs) => txs.len(), - BlockTransactionHashesInner::Hashes(txs) => txs.len(), - BlockTransactionHashesInner::Uncle => 0, - } - } -} - -impl DoubleEndedIterator for BlockTransactionHashes<'_, Transaction> { - #[inline] - fn next_back(&mut self) -> Option { - match &mut self.0 { - BlockTransactionHashesInner::Full(txs) => txs.next_back().map(|tx| &tx.hash), - BlockTransactionHashesInner::Hashes(txs) => txs.next_back(), - BlockTransactionHashesInner::Uncle => None, - } - } -} - -impl<'a> std::iter::FusedIterator for BlockTransactionHashes<'a, Transaction> {} - -/// An Iterator over the transaction hashes of a block. -/// -/// See [`BlockTransactions::hashes_mut`]. -#[derive(Debug)] -pub struct BlockTransactionHashesMut<'a, T = Transaction>(BlockTransactionHashesInnerMut<'a, T>); - -#[derive(Debug)] -enum BlockTransactionHashesInnerMut<'a, T = Transaction> { - Hashes(std::slice::IterMut<'a, B256>), - Full(std::slice::IterMut<'a, T>), - Uncle, -} - -impl<'a, T> BlockTransactionHashesMut<'a, T> { - #[inline] - fn new(txs: &'a mut BlockTransactions) -> Self { - Self(match txs { - BlockTransactions::Hashes(txs) => { - BlockTransactionHashesInnerMut::Hashes(txs.iter_mut()) - } - BlockTransactions::Full(txs) => BlockTransactionHashesInnerMut::Full(txs.iter_mut()), - BlockTransactions::Uncle => BlockTransactionHashesInnerMut::Uncle, - }) - } -} - -impl<'a> Iterator for BlockTransactionHashesMut<'a, Transaction> { - type Item = &'a mut B256; - - #[inline] - fn next(&mut self) -> Option { - match &mut self.0 { - BlockTransactionHashesInnerMut::Full(txs) => txs.next().map(|tx| &mut tx.hash), - BlockTransactionHashesInnerMut::Hashes(txs) => txs.next(), - BlockTransactionHashesInnerMut::Uncle => None, - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - match &self.0 { - BlockTransactionHashesInnerMut::Full(txs) => txs.size_hint(), - BlockTransactionHashesInnerMut::Hashes(txs) => txs.size_hint(), - BlockTransactionHashesInnerMut::Uncle => (0, Some(0)), - } - } -} - -impl ExactSizeIterator for BlockTransactionHashesMut<'_, Transaction> { - #[inline] - fn len(&self) -> usize { - match &self.0 { - BlockTransactionHashesInnerMut::Full(txs) => txs.len(), - BlockTransactionHashesInnerMut::Hashes(txs) => txs.len(), - BlockTransactionHashesInnerMut::Uncle => 0, - } - } -} - -impl DoubleEndedIterator for BlockTransactionHashesMut<'_, Transaction> { - #[inline] - fn next_back(&mut self) -> Option { - match &mut self.0 { - BlockTransactionHashesInnerMut::Full(txs) => txs.next_back().map(|tx| &mut tx.hash), - BlockTransactionHashesInnerMut::Hashes(txs) => txs.next_back(), - BlockTransactionHashesInnerMut::Uncle => None, - } - } -} - -impl<'a> std::iter::FusedIterator for BlockTransactionHashesMut<'a, Transaction> {} - -/// Determines how the `transactions` field of [Block] should be filled. -/// -/// This essentially represents the `full:bool` argument in RPC calls that determine whether the -/// response should include full transaction objects or just the hashes. -#[derive(Clone, Copy, Debug, PartialEq, Eq, Default)] -pub enum BlockTransactionsKind { - /// Only include hashes: [BlockTransactions::Hashes] - #[default] - Hashes, - /// Include full transaction objects: [BlockTransactions::Full] - Full, -} - -impl From for BlockTransactionsKind { - fn from(is_full: bool) -> Self { - if is_full { - Self::Full - } else { - Self::Hashes - } - } -} - -impl From for bool { - fn from(kind: BlockTransactionsKind) -> Self { - match kind { - BlockTransactionsKind::Full => true, - BlockTransactionsKind::Hashes => false, - } - } -} - /// Error that can occur when converting other types to blocks #[derive(Clone, Copy, Debug, thiserror::Error)] pub enum BlockError { @@ -648,15 +331,6 @@ mod tests { let _: Header = Header::arbitrary(&mut arbitrary::Unstructured::new(&bytes)).unwrap(); } - #[test] - fn test_full_conversion() { - let full = true; - assert_eq!(BlockTransactionsKind::Full, full.into()); - - let full = false; - assert_eq!(BlockTransactionsKind::Hashes, full.into()); - } - #[test] #[cfg(feature = "jsonrpsee-types")] fn serde_json_header() { diff --git a/crates/rpc-types-eth/src/lib.rs b/crates/rpc-types-eth/src/lib.rs index dd11ef33b68..85870935fc9 100644 --- a/crates/rpc-types-eth/src/lib.rs +++ b/crates/rpc-types-eth/src/lib.rs @@ -14,6 +14,10 @@ pub use account::*; mod block; pub use block::*; +pub use alloy_network_primitives::{ + BlockTransactionHashes, BlockTransactions, BlockTransactionsKind, +}; + mod call; pub use call::{Bundle, EthCallResponse, StateContext, TransactionIndex}; diff --git a/crates/rpc-types-eth/src/transaction/mod.rs b/crates/rpc-types-eth/src/transaction/mod.rs index 4d567e790d2..40f00c9f78d 100644 --- a/crates/rpc-types-eth/src/transaction/mod.rs +++ b/crates/rpc-types-eth/src/transaction/mod.rs @@ -5,6 +5,7 @@ use alloy_consensus::{ TxLegacy, TxType, }; use alloy_eips::eip7702::SignedAuthorization; +use alloy_network_primitives::TransactionResponse; use alloy_primitives::{Address, BlockHash, Bytes, ChainId, TxHash, TxKind, B256, U256}; use alloy_serde::OtherFields; use serde::{Deserialize, Serialize}; @@ -276,6 +277,31 @@ impl TryFrom for TxEnvelope { } } +impl TransactionResponse for Transaction { + fn tx_hash(&self) -> B256 { + self.hash + } + + fn from(&self) -> Address { + self.from + } + + fn to(&self) -> Option
{ + self.to + } + + fn value(&self) -> U256 { + self.value + } + + fn gas(&self) -> u128 { + self.gas + } + + fn input(&self) -> &Bytes { + &self.input + } +} #[cfg(test)] mod tests { use super::*; diff --git a/crates/rpc-types-eth/src/transaction/receipt.rs b/crates/rpc-types-eth/src/transaction/receipt.rs index 8d49e1488dc..a95e5dce66b 100644 --- a/crates/rpc-types-eth/src/transaction/receipt.rs +++ b/crates/rpc-types-eth/src/transaction/receipt.rs @@ -1,6 +1,7 @@ use crate::Log; -use alloy_consensus::{AnyReceiptEnvelope, ReceiptEnvelope, TxType}; +use alloy_consensus::{AnyReceiptEnvelope, ReceiptEnvelope, TxReceipt, TxType}; use alloy_eips::eip7702::SignedAuthorization; +use alloy_network_primitives::ReceiptResponse; use alloy_primitives::{Address, BlockHash, TxHash, B256}; use alloy_serde::WithOtherFields; use serde::{Deserialize, Serialize}; @@ -128,6 +129,24 @@ impl TransactionReceipt { #[doc(alias = "AnyTxReceipt")] pub type AnyTransactionReceipt = WithOtherFields>>; +impl> ReceiptResponse for TransactionReceipt { + fn contract_address(&self) -> Option { + self.contract_address + } + + fn status(&self) -> bool { + self.inner.status() + } + + fn block_hash(&self) -> Option { + self.block_hash + } + + fn block_number(&self) -> Option { + self.block_number + } +} + #[cfg(test)] mod test { use super::*; From aac27bc39b2e9d5d2c4a7f4e4703e3120e6ac58a Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Fri, 26 Jul 2024 13:01:50 +0200 Subject: [PATCH 052/186] chore: re-export and document network-primitives (#1107) --- README.md | 2 ++ crates/network/src/lib.rs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 20268026730..96640256a24 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ This repository contains the following crates: - [`alloy-genesis`] - Ethereum genesis file definitions - [`alloy-json-rpc`] - Core data types for JSON-RPC 2.0 clients - [`alloy-network`] - Network abstraction for RPC types + - [`alloy-network-primitives`] - Primitive types for the network abstraction - [`alloy-node-bindings`] - Ethereum execution-layer client bindings - [`alloy-provider`] - Interface with an Ethereum blockchain - [`alloy-pubsub`] - Ethereum JSON-RPC [publish-subscribe] tower service and type definitions @@ -77,6 +78,7 @@ This repository contains the following crates: [`alloy-genesis`]: https://github.com/alloy-rs/alloy/tree/main/crates/genesis [`alloy-json-rpc`]: https://github.com/alloy-rs/alloy/tree/main/crates/json-rpc [`alloy-network`]: https://github.com/alloy-rs/alloy/tree/main/crates/network +[`alloy-network-primitives`]: https://github.com/alloy-rs/alloy/tree/main/crates/network-primitives [`alloy-node-bindings`]: https://github.com/alloy-rs/alloy/tree/main/crates/node-bindings [`alloy-provider`]: https://github.com/alloy-rs/alloy/tree/main/crates/provider [`alloy-pubsub`]: https://github.com/alloy-rs/alloy/tree/main/crates/pubsub diff --git a/crates/network/src/lib.rs b/crates/network/src/lib.rs index 0719e452c57..55a931ed40f 100644 --- a/crates/network/src/lib.rs +++ b/crates/network/src/lib.rs @@ -24,7 +24,7 @@ mod any; pub use any::{AnyNetwork, AnyTxType}; pub use alloy_eips::eip2718; -pub use alloy_network_primitives::{ReceiptResponse, TransactionResponse}; +pub use alloy_network_primitives::{self as primitives, ReceiptResponse, TransactionResponse}; /// Captures type info for network-specific RPC requests/responses. /// From fa01c2ab9174abcd9521624ef341fcfea3d08356 Mon Sep 17 00:00:00 2001 From: m1stoyanov <133634888+m1stoyanov@users.noreply.github.com> Date: Fri, 26 Jul 2024 17:37:32 +0300 Subject: [PATCH 053/186] fix: make Parity TraceResults output optional (#1102) * Update parity.rs Bytes to Option That will resolve the issue when the RPC server returns "output": null, as Nethermind does. * Use null_as_default for handling null output and added test --- crates/rpc-types-trace/src/parity.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/crates/rpc-types-trace/src/parity.rs b/crates/rpc-types-trace/src/parity.rs index 21abea91bb2..b6794694eb7 100644 --- a/crates/rpc-types-trace/src/parity.rs +++ b/crates/rpc-types-trace/src/parity.rs @@ -29,6 +29,7 @@ pub enum TraceType { #[serde(rename_all = "camelCase")] pub struct TraceResults { /// Output of the trace + #[serde(deserialize_with = "alloy_serde::null_as_default")] pub output: Bytes, /// Enabled if [TraceType::StateDiff] is provided pub state_diff: Option, @@ -821,4 +822,31 @@ mod tests { let serialized = serde_json::to_string_pretty(&trace).unwrap(); similar_asserts::assert_eq!(serialized, reference_data); } + #[test] + fn test_nethermind_trace_result_null_output_value() { + let reference_data = r#"{ + "output": null, + "stateDiff": { + "0x5e1d1eb61e1164d5a50b28c575da73a29595dff7": { + "balance": "=", + "code": "=", + "nonce": "=", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000005": { + "*": { + "from": "0x0000000000000000000000000000000000000000000000000000000000042f66", + "to": "0x0000000000000000000000000000000000000000000000000000000000042f67" + } + } + } + } + }, + "trace": [], + "vmTrace": null, + "transactionHash": "0xe56a5e7455c45b1842b35dbcab9d024b21870ee59820525091e183b573b4f9eb" +}"#; + let trace = + serde_json::from_str::(reference_data).unwrap(); + assert_eq!(trace.full_trace.output, Bytes::default()); + } } From b3fdd807781ee95c0b5b3672a7b0cff43f8bd33d Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Wed, 31 Jul 2024 20:51:13 +0200 Subject: [PATCH 054/186] rpc: derive arbitrary for `TransactionRequest` (#1113) * rpc: derive arbitrary for TransactionRequest * fix deny --- crates/rpc-types-eth/src/transaction/request.rs | 3 +++ deny.toml | 2 ++ 2 files changed, 5 insertions(+) diff --git a/crates/rpc-types-eth/src/transaction/request.rs b/crates/rpc-types-eth/src/transaction/request.rs index 36c85addd3c..b61d2875cfb 100644 --- a/crates/rpc-types-eth/src/transaction/request.rs +++ b/crates/rpc-types-eth/src/transaction/request.rs @@ -8,7 +8,9 @@ use alloy_consensus::{ use alloy_primitives::{Address, Bytes, ChainId, TxKind, B256, U256}; use serde::{Deserialize, Serialize}; use std::hash::Hash; + /// Represents _all_ transaction requests to/from RPC. +#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] #[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] #[doc(alias = "TxRequest")] @@ -484,6 +486,7 @@ impl TransactionRequest { /// /// If both fields are set, it is expected that they contain the same value, otherwise an error is /// returned. +#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] #[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)] #[doc(alias = "TxInput")] pub struct TransactionInput { diff --git a/deny.toml b/deny.toml index 901fbbe7947..2278d2ddde4 100644 --- a/deny.toml +++ b/deny.toml @@ -16,6 +16,7 @@ allow = [ "Apache-2.0", "Apache-2.0 WITH LLVM-exception", "BSD-3-Clause", + "BSD-2-Clause", "0BSD", "ISC", "Unicode-3.0", @@ -32,6 +33,7 @@ exceptions = [ # https://tldrlegal.com/license/creative-commons-cc0-1.0-universal { allow = ["CC0-1.0"], name = "tiny-keccak" }, { allow = ["CC0-1.0"], name = "trezor-client" }, + { allow = ["BSD-2-Clause"], name = "zerocopy" }, ] [[licenses.clarify]] From 4a0a641af92aee67286081dda562a9698888ba61 Mon Sep 17 00:00:00 2001 From: hbdgr Date: Thu, 1 Aug 2024 00:14:14 +0200 Subject: [PATCH 055/186] docs: readme fix (#1114) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 96640256a24..1f710d763ba 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ cargo add alloy --features full Alternatively, you can add the following to your `Cargo.toml` file: ```toml -alloy = { version = "0.1", features = ["full"] } +alloy = { version = "0.2", features = ["full"] } ``` For a more fine-grained control over the features you wish to include, you can add the individual crates to your `Cargo.toml` file, or use the `alloy` crate with the features you need. From bad667e15f0f74089680f851b0fc6a749f5a09af Mon Sep 17 00:00:00 2001 From: Roman Krasiuk Date: Thu, 1 Aug 2024 09:36:28 -0700 Subject: [PATCH 056/186] feat(engine-types): `PayloadError::PrePragueBlockWithEip7702Transactions` (#1116) --- crates/rpc-types-engine/src/payload.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/rpc-types-engine/src/payload.rs b/crates/rpc-types-engine/src/payload.rs index 82269f3a378..d79701657be 100644 --- a/crates/rpc-types-engine/src/payload.rs +++ b/crates/rpc-types-engine/src/payload.rs @@ -813,6 +813,9 @@ pub enum PayloadError { /// cancun fields missing in post-cancun payload. #[error("cancun fields missing in post-cancun payload")] PostCancunWithoutCancunFields, + /// blob transactions present in pre-prague payload. + #[error("eip 7702 transactions present in pre-prague payload")] + PrePragueBlockWithEip7702Transactions, /// Invalid payload block hash. #[error("block hash mismatch: want {consensus}, got {execution}")] From 8e5a9fbd1b70d5bf31d5615246b07fd2eac60209 Mon Sep 17 00:00:00 2001 From: Miguel Date: Thu, 1 Aug 2024 14:17:29 -0300 Subject: [PATCH 057/186] Add `AccessListResult` type (EIP-2930) (#1110) * replace type, change type of result and add type in mod.rs * add new methods * add docs and impl * docs linking * clippy * rustmft --------- Co-authored-by: Matthias Seitz --- crates/eips/src/eip2930.rs | 40 +++++++++++++++++++-- crates/provider/src/provider/trait.rs | 6 ++-- crates/rpc-types-eth/src/transaction/mod.rs | 2 +- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/crates/eips/src/eip2930.rs b/crates/eips/src/eip2930.rs index 2686d7bf8ec..e215eec9e04 100644 --- a/crates/eips/src/eip2930.rs +++ b/crates/eips/src/eip2930.rs @@ -3,7 +3,7 @@ //! [EIP-2930]: https://eips.ethereum.org/EIPS/eip-2930 #[cfg(not(feature = "std"))] -use alloc::vec::Vec; +use alloc::{string::String, vec::Vec}; use alloy_primitives::{Address, B256, U256}; use alloy_rlp::{RlpDecodable, RlpDecodableWrapper, RlpEncodable, RlpEncodableWrapper}; @@ -141,6 +141,39 @@ pub struct AccessListWithGasUsed { pub gas_used: U256, } +/// `AccessListResult` for handling errors from `eth_createAccessList` +#[derive(Clone, Debug, Default, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] +pub struct AccessListResult { + /// List with accounts accessed during transaction. + pub access_list: AccessList, + /// Estimated gas used with access list. + pub gas_used: U256, + /// Optional error message if the transaction failed. + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] + pub error: Option, +} + +impl AccessListResult { + /// Ensures the result is OK, returning [`AccessListWithGasUsed`] if so, or an error message if + /// not. + pub fn ensure_ok(self) -> Result { + match self.error { + Some(err) => Err(err), + None => { + Ok(AccessListWithGasUsed { access_list: self.access_list, gas_used: self.gas_used }) + } + } + } + + /// Checks if there is an error in the result. + #[inline] + pub const fn is_err(&self) -> bool { + self.error.is_some() + } +} + #[cfg(all(test, feature = "serde"))] mod tests { use super::*; @@ -158,15 +191,16 @@ mod tests { #[test] fn access_list_with_gas_used() { - let list = AccessListWithGasUsed { + let list = AccessListResult { access_list: AccessList(vec![ AccessListItem { address: Address::ZERO, storage_keys: vec![B256::ZERO] }, AccessListItem { address: Address::ZERO, storage_keys: vec![B256::ZERO] }, ]), gas_used: U256::from(100), + error: None, }; let json = serde_json::to_string(&list).unwrap(); - let list2 = serde_json::from_str::(&json).unwrap(); + let list2 = serde_json::from_str(&json).unwrap(); assert_eq!(list, list2); } } diff --git a/crates/provider/src/provider/trait.rs b/crates/provider/src/provider/trait.rs index 6af73c6744b..b90fc0ffbd7 100644 --- a/crates/provider/src/provider/trait.rs +++ b/crates/provider/src/provider/trait.rs @@ -15,8 +15,8 @@ use alloy_primitives::{ }; use alloy_rpc_client::{ClientRef, PollerBuilder, RpcCall, WeakClient}; use alloy_rpc_types_eth::{ - AccessListWithGasUsed, Block, BlockId, BlockNumberOrTag, EIP1186AccountProofResponse, - FeeHistory, Filter, FilterChanges, Log, SyncStatus, + AccessListResult, Block, BlockId, BlockNumberOrTag, EIP1186AccountProofResponse, FeeHistory, + Filter, FilterChanges, Log, SyncStatus, }; use alloy_transport::{BoxTransport, Transport, TransportErrorKind, TransportResult}; use serde_json::value::RawValue; @@ -163,7 +163,7 @@ pub trait Provider: fn create_access_list<'a>( &self, request: &'a N::TransactionRequest, - ) -> RpcWithBlock { + ) -> RpcWithBlock { RpcWithBlock::new(self.weak_client(), "eth_createAccessList", request) } diff --git a/crates/rpc-types-eth/src/transaction/mod.rs b/crates/rpc-types-eth/src/transaction/mod.rs index 40f00c9f78d..c81ecf414e7 100644 --- a/crates/rpc-types-eth/src/transaction/mod.rs +++ b/crates/rpc-types-eth/src/transaction/mod.rs @@ -12,7 +12,7 @@ use serde::{Deserialize, Serialize}; pub use alloy_consensus::BlobTransactionSidecar; pub use alloy_eips::{ - eip2930::{AccessList, AccessListItem, AccessListWithGasUsed}, + eip2930::{AccessList, AccessListItem, AccessListResult}, eip7702::Authorization, }; From 74efdec09fc09ffd41e6294f97dd273e99c13eb4 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Thu, 1 Aug 2024 19:19:03 +0200 Subject: [PATCH 058/186] chore: correctly cfg unused type (#1117) --- crates/provider/src/builder.rs | 1 + crates/provider/src/provider/trait.rs | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/provider/src/builder.rs b/crates/provider/src/builder.rs index 3871ac86865..802daae0c84 100644 --- a/crates/provider/src/builder.rs +++ b/crates/provider/src/builder.rs @@ -346,6 +346,7 @@ impl ProviderBuilder { } } +#[cfg(any(test, feature = "anvil-node"))] type JoinedEthereumWalletFiller = JoinFill>; #[cfg(any(test, feature = "anvil-node"))] diff --git a/crates/provider/src/provider/trait.rs b/crates/provider/src/provider/trait.rs index b90fc0ffbd7..4d2664718af 100644 --- a/crates/provider/src/provider/trait.rs +++ b/crates/provider/src/provider/trait.rs @@ -148,7 +148,10 @@ pub trait Provider: /// Not all client implementations support state overrides. #[doc(alias = "eth_call")] #[doc(alias = "call_with_overrides")] - fn call<'req>(&self, tx: &'req N::TransactionRequest) -> EthCall<'req, 'static, T, N, Bytes> { + fn call<'req, 'state>( + &self, + tx: &'req N::TransactionRequest, + ) -> EthCall<'req, 'state, T, N, Bytes> { EthCall::new(self.weak_client(), tx) } From a011cc5dcf97473217bcb5d9c2b6d0903eb68752 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Thu, 1 Aug 2024 21:46:05 +0200 Subject: [PATCH 059/186] chore(rpc): Make `Deserialize` impl for `FilterChanges` generic over transaction (#1118) Make Deserialize impl for FilterChanges generic over transaction --- crates/rpc-types-eth/src/filter.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/rpc-types-eth/src/filter.rs b/crates/rpc-types-eth/src/filter.rs index 19f92f91411..2adf2022d6e 100644 --- a/crates/rpc-types-eth/src/filter.rs +++ b/crates/rpc-types-eth/src/filter.rs @@ -1021,7 +1021,10 @@ mod empty_array { } } -impl<'de> Deserialize<'de> for FilterChanges { +impl<'de, T> Deserialize<'de> for FilterChanges +where + T: Deserialize<'de>, +{ fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, From 3bf3618b111df609bafedbd648664e2d82122c47 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Fri, 2 Aug 2024 13:51:25 +0200 Subject: [PATCH 060/186] chore: release 0.2.1 --- CHANGELOG.md | 41 ++++++++++++- Cargo.toml | 2 +- crates/alloy/CHANGELOG.md | 5 +- crates/consensus/CHANGELOG.md | 10 +++- crates/contract/CHANGELOG.md | 8 ++- crates/eip7547/CHANGELOG.md | 4 +- crates/eips/CHANGELOG.md | 10 +++- crates/genesis/CHANGELOG.md | 8 ++- crates/json-rpc/CHANGELOG.md | 8 ++- crates/network-primitives/CHANGELOG.md | 79 ++++++++++++++++++++++++++ crates/network/CHANGELOG.md | 9 ++- crates/node-bindings/CHANGELOG.md | 5 +- crates/provider/CHANGELOG.md | 14 ++++- crates/pubsub/CHANGELOG.md | 4 +- crates/rpc-client/CHANGELOG.md | 8 ++- crates/rpc-types-admin/CHANGELOG.md | 5 +- crates/rpc-types-anvil/CHANGELOG.md | 4 +- crates/rpc-types-beacon/CHANGELOG.md | 4 +- crates/rpc-types-engine/CHANGELOG.md | 12 +++- crates/rpc-types-eth/CHANGELOG.md | 20 ++++++- crates/rpc-types-mev/CHANGELOG.md | 5 +- crates/rpc-types-trace/CHANGELOG.md | 10 +++- crates/rpc-types-txpool/CHANGELOG.md | 4 +- crates/rpc-types/CHANGELOG.md | 4 +- crates/serde/CHANGELOG.md | 3 +- crates/signer-aws/CHANGELOG.md | 4 +- crates/signer-gcp/CHANGELOG.md | 4 +- crates/signer-ledger/CHANGELOG.md | 4 +- crates/signer-local/CHANGELOG.md | 4 +- crates/signer-trezor/CHANGELOG.md | 4 +- crates/signer/CHANGELOG.md | 8 ++- crates/transport-http/CHANGELOG.md | 4 +- crates/transport-ipc/CHANGELOG.md | 4 +- crates/transport-ws/CHANGELOG.md | 4 +- crates/transport/CHANGELOG.md | 12 +++- 35 files changed, 273 insertions(+), 65 deletions(-) create mode 100644 crates/network-primitives/CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f41da2a36f..6c9a75730df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,10 +5,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 ### Bug Fixes +- Make Parity TraceResults output optional ([#1102](https://github.com/alloy-rs/alloy/issues/1102)) +- Correctly trim eip7251 bytecode ([#1105](https://github.com/alloy-rs/alloy/issues/1105)) +- [eips] Make SignedAuthorizationList arbitrary less fallible ([#1084](https://github.com/alloy-rs/alloy/issues/1084)) +- [node-bindings] Backport fix from ethers-rs ([#1081](https://github.com/alloy-rs/alloy/issues/1081)) - Trim conflicting key `max_fee_per_blob_gas` from Eip1559 tx type ([#1064](https://github.com/alloy-rs/alloy/issues/1064)) - [provider] Prevent panic from having 0 keys when calling `on_anvil_with_wallet_and_config` ([#1055](https://github.com/alloy-rs/alloy/issues/1055)) - Require storageKeys value broken bincode serialization from [#955](https://github.com/alloy-rs/alloy/issues/955) ([#1058](https://github.com/alloy-rs/alloy/issues/1058)) @@ -19,10 +23,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Dependencies +- Bump jsonrpsee 0.24 ([#1067](https://github.com/alloy-rs/alloy/issues/1067)) - [deps] Bump Trezor client to `=0.1.4` to fix signing bug ([#1045](https://github.com/alloy-rs/alloy/issues/1045)) +### Documentation + +- Readme fix ([#1114](https://github.com/alloy-rs/alloy/issues/1114)) +- Update links to use docs.rs ([#1066](https://github.com/alloy-rs/alloy/issues/1066)) + ### Features +- [engine-types] `PayloadError::PrePragueBlockWithEip7702Transactions` ([#1116](https://github.com/alloy-rs/alloy/issues/1116)) +- Use EncodableSignature for tx encoding ([#1100](https://github.com/alloy-rs/alloy/issues/1100)) +- Eth_simulateV1 Request / Response types ([#1042](https://github.com/alloy-rs/alloy/issues/1042)) +- Add helper for decoding custom errors ([#1098](https://github.com/alloy-rs/alloy/issues/1098)) +- Enable more features transitively in meta crate ([#1097](https://github.com/alloy-rs/alloy/issues/1097)) +- [rpc/trace] Filter matches with trace ([#1090](https://github.com/alloy-rs/alloy/issues/1090)) +- Feat(rpc-type-eth) convert vec TxReq to bundle ([#1091](https://github.com/alloy-rs/alloy/issues/1091)) +- [eip] Make 7702 auth recovery fallible ([#1082](https://github.com/alloy-rs/alloy/issues/1082)) +- [json-rpc] Implement `From for Id` and `From for Id` ([#1088](https://github.com/alloy-rs/alloy/issues/1088)) +- [consensus] Add `From` for `Request` ([#1083](https://github.com/alloy-rs/alloy/issues/1083)) +- Feat(provider) : introduction to eth_sendRawTransactionConditional RPC endpoint type ([#1009](https://github.com/alloy-rs/alloy/issues/1009)) - Expose encoded_len_with_signature() ([#1063](https://github.com/alloy-rs/alloy/issues/1063)) - Add 7702 tx type ([#1046](https://github.com/alloy-rs/alloy/issues/1046)) - [rpc-types-eth] Serde flatten `BlobTransactionSidecar` in tx req ([#1054](https://github.com/alloy-rs/alloy/issues/1054)) @@ -39,15 +60,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks -- Release 0.2.0 +- Release 0.2.1 +- [rpc] Make `Deserialize` impl for `FilterChanges` generic over transaction ([#1118](https://github.com/alloy-rs/alloy/issues/1118)) +- Correctly cfg unused type ([#1117](https://github.com/alloy-rs/alloy/issues/1117)) +- Re-export and document network-primitives ([#1107](https://github.com/alloy-rs/alloy/issues/1107)) +- Allow override all group ([#1104](https://github.com/alloy-rs/alloy/issues/1104)) +- Chore : fix typos ([#1087](https://github.com/alloy-rs/alloy/issues/1087)) +- Export rpc account type ([#1075](https://github.com/alloy-rs/alloy/issues/1075)) - Release 0.2.0 - Make auth mandatory in recovered auth ([#1047](https://github.com/alloy-rs/alloy/issues/1047)) - Trace output utils ([#1027](https://github.com/alloy-rs/alloy/issues/1027)) - Fix unnameable types ([#1029](https://github.com/alloy-rs/alloy/issues/1029)) - Add payloadbodies v2 to capabilities set ([#1025](https://github.com/alloy-rs/alloy/issues/1025)) +### Other + +- Add `AccessListResult` type (EIP-2930) ([#1110](https://github.com/alloy-rs/alloy/issues/1110)) +- Derive arbitrary for `TransactionRequest` ([#1113](https://github.com/alloy-rs/alloy/issues/1113)) +- Fix typo in genesis ([#1096](https://github.com/alloy-rs/alloy/issues/1096)) +- Removing async get account ([#1080](https://github.com/alloy-rs/alloy/issues/1080)) +- Added stages to the sync info rpc type ([#1079](https://github.com/alloy-rs/alloy/issues/1079)) +- `alloy-consensus` should use `alloy_primitives::Sealable` ([#1072](https://github.com/alloy-rs/alloy/issues/1072)) + ### Refactor +- Add network-primitives ([#1101](https://github.com/alloy-rs/alloy/issues/1101)) - Replace `U64` with `u64` ([#1057](https://github.com/alloy-rs/alloy/issues/1057)) ### Styling diff --git a/Cargo.toml b/Cargo.toml index 590aa9fc7a8..301c474fd48 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = ["crates/*"] resolver = "2" [workspace.package] -version = "0.2.0" +version = "0.2.1" edition = "2021" rust-version = "1.76" authors = ["Alloy Contributors"] diff --git a/crates/alloy/CHANGELOG.md b/crates/alloy/CHANGELOG.md index 87fe5d40423..2b4a653a6e8 100644 --- a/crates/alloy/CHANGELOG.md +++ b/crates/alloy/CHANGELOG.md @@ -5,15 +5,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 ### Features +- Enable more features transitively in meta crate ([#1097](https://github.com/alloy-rs/alloy/issues/1097)) - Add `rpc-types-mev` feature to meta crate ([#1040](https://github.com/alloy-rs/alloy/issues/1040)) ### Miscellaneous Tasks -- Release 0.2.0 +- Release 0.2.1 - Release 0.2.0 ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 diff --git a/crates/consensus/CHANGELOG.md b/crates/consensus/CHANGELOG.md index f866a1a7d3c..ac3840c789d 100644 --- a/crates/consensus/CHANGELOG.md +++ b/crates/consensus/CHANGELOG.md @@ -5,18 +5,24 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 ### Features +- Use EncodableSignature for tx encoding ([#1100](https://github.com/alloy-rs/alloy/issues/1100)) +- [consensus] Add `From` for `Request` ([#1083](https://github.com/alloy-rs/alloy/issues/1083)) - Expose encoded_len_with_signature() ([#1063](https://github.com/alloy-rs/alloy/issues/1063)) - Add 7702 tx type ([#1046](https://github.com/alloy-rs/alloy/issues/1046)) - Impl `arbitrary` for tx structs ([#1050](https://github.com/alloy-rs/alloy/issues/1050)) ### Miscellaneous Tasks +- Chore : fix typos ([#1087](https://github.com/alloy-rs/alloy/issues/1087)) - Release 0.2.0 -- Release 0.2.0 + +### Other + +- `alloy-consensus` should use `alloy_primitives::Sealable` ([#1072](https://github.com/alloy-rs/alloy/issues/1072)) ### Styling diff --git a/crates/contract/CHANGELOG.md b/crates/contract/CHANGELOG.md index 43945c28fe7..9dc353d0561 100644 --- a/crates/contract/CHANGELOG.md +++ b/crates/contract/CHANGELOG.md @@ -5,14 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 ### Miscellaneous Tasks -- Release 0.2.0 +- Release 0.2.1 - Release 0.2.0 - Fix unnameable types ([#1029](https://github.com/alloy-rs/alloy/issues/1029)) +### Refactor + +- Add network-primitives ([#1101](https://github.com/alloy-rs/alloy/issues/1101)) + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Miscellaneous Tasks diff --git a/crates/eip7547/CHANGELOG.md b/crates/eip7547/CHANGELOG.md index 516d9874b5f..9e0795538dd 100644 --- a/crates/eip7547/CHANGELOG.md +++ b/crates/eip7547/CHANGELOG.md @@ -5,11 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 ### Miscellaneous Tasks -- Release 0.2.0 +- Release 0.2.1 - Release 0.2.0 ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 diff --git a/crates/eips/CHANGELOG.md b/crates/eips/CHANGELOG.md index 382eff41105..a5424f88e7a 100644 --- a/crates/eips/CHANGELOG.md +++ b/crates/eips/CHANGELOG.md @@ -5,16 +5,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 ### Bug Fixes +- Correctly trim eip7251 bytecode ([#1105](https://github.com/alloy-rs/alloy/issues/1105)) +- [eips] Make SignedAuthorizationList arbitrary less fallible ([#1084](https://github.com/alloy-rs/alloy/issues/1084)) - Require storageKeys value broken bincode serialization from [#955](https://github.com/alloy-rs/alloy/issues/955) ([#1058](https://github.com/alloy-rs/alloy/issues/1058)) - Cargo fmt ([#1044](https://github.com/alloy-rs/alloy/issues/1044)) - [eip7702] Add correct rlp decode/encode ([#1034](https://github.com/alloy-rs/alloy/issues/1034)) ### Features +- [eip] Make 7702 auth recovery fallible ([#1082](https://github.com/alloy-rs/alloy/issues/1082)) - Add authorization list to rpc transaction and tx receipt types ([#1051](https://github.com/alloy-rs/alloy/issues/1051)) - Generate valid signed auth signatures ([#1041](https://github.com/alloy-rs/alloy/issues/1041)) - Add arbitrary to auth ([#1036](https://github.com/alloy-rs/alloy/issues/1036)) @@ -22,8 +25,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.2.0 - Make auth mandatory in recovered auth ([#1047](https://github.com/alloy-rs/alloy/issues/1047)) +### Other + +- Add `AccessListResult` type (EIP-2930) ([#1110](https://github.com/alloy-rs/alloy/issues/1110)) + ### Styling - Remove proptest in all crates and Arbitrary derives ([#966](https://github.com/alloy-rs/alloy/issues/966)) diff --git a/crates/genesis/CHANGELOG.md b/crates/genesis/CHANGELOG.md index a44f3b900df..2a74f64d576 100644 --- a/crates/genesis/CHANGELOG.md +++ b/crates/genesis/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 ### Features @@ -13,8 +13,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.2.1 - Release 0.2.0 -- Release 0.2.0 + +### Other + +- Fix typo in genesis ([#1096](https://github.com/alloy-rs/alloy/issues/1096)) ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 diff --git a/crates/json-rpc/CHANGELOG.md b/crates/json-rpc/CHANGELOG.md index ac25e512b06..cb5d37d600d 100644 --- a/crates/json-rpc/CHANGELOG.md +++ b/crates/json-rpc/CHANGELOG.md @@ -5,11 +5,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 + +### Features + +- Add helper for decoding custom errors ([#1098](https://github.com/alloy-rs/alloy/issues/1098)) +- [json-rpc] Implement `From for Id` and `From for Id` ([#1088](https://github.com/alloy-rs/alloy/issues/1088)) ### Miscellaneous Tasks -- Release 0.2.0 - Release 0.2.0 ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 diff --git a/crates/network-primitives/CHANGELOG.md b/crates/network-primitives/CHANGELOG.md new file mode 100644 index 00000000000..11ab247977c --- /dev/null +++ b/crates/network-primitives/CHANGELOG.md @@ -0,0 +1,79 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 + +### Miscellaneous Tasks + +- Release 0.2.1 + +### Refactor + +- Add network-primitives ([#1101](https://github.com/alloy-rs/alloy/issues/1101)) + +[`alloy`]: https://crates.io/crates/alloy +[alloy]: https://crates.io/crates/alloy +[`alloy-core`]: https://crates.io/crates/alloy-core +[alloy-core]: https://crates.io/crates/alloy-core +[`alloy-consensus`]: https://crates.io/crates/alloy-consensus +[alloy-consensus]: https://crates.io/crates/alloy-consensus +[`alloy-contract`]: https://crates.io/crates/alloy-contract +[alloy-contract]: https://crates.io/crates/alloy-contract +[`alloy-eips`]: https://crates.io/crates/alloy-eips +[alloy-eips]: https://crates.io/crates/alloy-eips +[`alloy-genesis`]: https://crates.io/crates/alloy-genesis +[alloy-genesis]: https://crates.io/crates/alloy-genesis +[`alloy-json-rpc`]: https://crates.io/crates/alloy-json-rpc +[alloy-json-rpc]: https://crates.io/crates/alloy-json-rpc +[`alloy-network`]: https://crates.io/crates/alloy-network +[alloy-network]: https://crates.io/crates/alloy-network +[`alloy-node-bindings`]: https://crates.io/crates/alloy-node-bindings +[alloy-node-bindings]: https://crates.io/crates/alloy-node-bindings +[`alloy-provider`]: https://crates.io/crates/alloy-provider +[alloy-provider]: https://crates.io/crates/alloy-provider +[`alloy-pubsub`]: https://crates.io/crates/alloy-pubsub +[alloy-pubsub]: https://crates.io/crates/alloy-pubsub +[`alloy-rpc-client`]: https://crates.io/crates/alloy-rpc-client +[alloy-rpc-client]: https://crates.io/crates/alloy-rpc-client +[`alloy-rpc-types`]: https://crates.io/crates/alloy-rpc-types +[alloy-rpc-types]: https://crates.io/crates/alloy-rpc-types +[`alloy-rpc-types-anvil`]: https://crates.io/crates/alloy-rpc-types-anvil +[alloy-rpc-types-anvil]: https://crates.io/crates/alloy-rpc-types-anvil +[`alloy-rpc-types-beacon`]: https://crates.io/crates/alloy-rpc-types-beacon +[alloy-rpc-types-beacon]: https://crates.io/crates/alloy-rpc-types-beacon +[`alloy-rpc-types-engine`]: https://crates.io/crates/alloy-rpc-types-engine +[alloy-rpc-types-engine]: https://crates.io/crates/alloy-rpc-types-engine +[`alloy-rpc-types-eth`]: https://crates.io/crates/alloy-rpc-types-eth +[alloy-rpc-types-eth]: https://crates.io/crates/alloy-rpc-types-eth +[`alloy-rpc-types-trace`]: https://crates.io/crates/alloy-rpc-types-trace +[alloy-rpc-types-trace]: https://crates.io/crates/alloy-rpc-types-trace +[`alloy-serde`]: https://crates.io/crates/alloy-serde +[alloy-serde]: https://crates.io/crates/alloy-serde +[`alloy-signer`]: https://crates.io/crates/alloy-signer +[alloy-signer]: https://crates.io/crates/alloy-signer +[`alloy-signer-aws`]: https://crates.io/crates/alloy-signer-aws +[alloy-signer-aws]: https://crates.io/crates/alloy-signer-aws +[`alloy-signer-gcp`]: https://crates.io/crates/alloy-signer-gcp +[alloy-signer-gcp]: https://crates.io/crates/alloy-signer-gcp +[`alloy-signer-ledger`]: https://crates.io/crates/alloy-signer-ledger +[alloy-signer-ledger]: https://crates.io/crates/alloy-signer-ledger +[`alloy-signer-local`]: https://crates.io/crates/alloy-signer-local +[alloy-signer-local]: https://crates.io/crates/alloy-signer-local +[`alloy-signer-trezor`]: https://crates.io/crates/alloy-signer-trezor +[alloy-signer-trezor]: https://crates.io/crates/alloy-signer-trezor +[`alloy-signer-wallet`]: https://crates.io/crates/alloy-signer-wallet +[alloy-signer-wallet]: https://crates.io/crates/alloy-signer-wallet +[`alloy-transport`]: https://crates.io/crates/alloy-transport +[alloy-transport]: https://crates.io/crates/alloy-transport +[`alloy-transport-http`]: https://crates.io/crates/alloy-transport-http +[alloy-transport-http]: https://crates.io/crates/alloy-transport-http +[`alloy-transport-ipc`]: https://crates.io/crates/alloy-transport-ipc +[alloy-transport-ipc]: https://crates.io/crates/alloy-transport-ipc +[`alloy-transport-ws`]: https://crates.io/crates/alloy-transport-ws +[alloy-transport-ws]: https://crates.io/crates/alloy-transport-ws + + diff --git a/crates/network/CHANGELOG.md b/crates/network/CHANGELOG.md index 9b2aa65b1bf..ef0ed84f3b7 100644 --- a/crates/network/CHANGELOG.md +++ b/crates/network/CHANGELOG.md @@ -5,14 +5,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 ### Miscellaneous Tasks -- Release 0.2.0 +- Release 0.2.1 +- Re-export and document network-primitives ([#1107](https://github.com/alloy-rs/alloy/issues/1107)) - Release 0.2.0 - Fix unnameable types ([#1029](https://github.com/alloy-rs/alloy/issues/1029)) +### Refactor + +- Add network-primitives ([#1101](https://github.com/alloy-rs/alloy/issues/1101)) + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Features diff --git a/crates/node-bindings/CHANGELOG.md b/crates/node-bindings/CHANGELOG.md index e65787af257..c62c5f6322b 100644 --- a/crates/node-bindings/CHANGELOG.md +++ b/crates/node-bindings/CHANGELOG.md @@ -5,16 +5,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 ### Bug Fixes +- [node-bindings] Backport fix from ethers-rs ([#1081](https://github.com/alloy-rs/alloy/issues/1081)) - [provider] Prevent panic from having 0 keys when calling `on_anvil_with_wallet_and_config` ([#1055](https://github.com/alloy-rs/alloy/issues/1055)) - [admin] Id in NodeInfo is string instead of B256 ([#1038](https://github.com/alloy-rs/alloy/issues/1038)) ### Miscellaneous Tasks -- Release 0.2.0 +- Release 0.2.1 - Release 0.2.0 ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 diff --git a/crates/provider/CHANGELOG.md b/crates/provider/CHANGELOG.md index 14bfae1615d..7ee14d13b7c 100644 --- a/crates/provider/CHANGELOG.md +++ b/crates/provider/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 ### Bug Fixes @@ -19,10 +19,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks -- Release 0.2.0 +- Release 0.2.1 +- Correctly cfg unused type ([#1117](https://github.com/alloy-rs/alloy/issues/1117)) - Release 0.2.0 - Fix unnameable types ([#1029](https://github.com/alloy-rs/alloy/issues/1029)) +### Other + +- Add `AccessListResult` type (EIP-2930) ([#1110](https://github.com/alloy-rs/alloy/issues/1110)) +- Removing async get account ([#1080](https://github.com/alloy-rs/alloy/issues/1080)) + +### Refactor + +- Add network-primitives ([#1101](https://github.com/alloy-rs/alloy/issues/1101)) + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Bug Fixes diff --git a/crates/pubsub/CHANGELOG.md b/crates/pubsub/CHANGELOG.md index 7403bfabfd2..2449052513e 100644 --- a/crates/pubsub/CHANGELOG.md +++ b/crates/pubsub/CHANGELOG.md @@ -5,11 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 ### Miscellaneous Tasks -- Release 0.2.0 +- Release 0.2.1 - Release 0.2.0 - Fix unnameable types ([#1029](https://github.com/alloy-rs/alloy/issues/1029)) diff --git a/crates/rpc-client/CHANGELOG.md b/crates/rpc-client/CHANGELOG.md index e4fc5179bd2..f645b508cf3 100644 --- a/crates/rpc-client/CHANGELOG.md +++ b/crates/rpc-client/CHANGELOG.md @@ -5,11 +5,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 + +### Features + +- [json-rpc] Implement `From for Id` and `From for Id` ([#1088](https://github.com/alloy-rs/alloy/issues/1088)) ### Miscellaneous Tasks -- Release 0.2.0 +- Release 0.2.1 - Release 0.2.0 - Fix unnameable types ([#1029](https://github.com/alloy-rs/alloy/issues/1029)) diff --git a/crates/rpc-types-admin/CHANGELOG.md b/crates/rpc-types-admin/CHANGELOG.md index 370e48150e6..860dc7b9388 100644 --- a/crates/rpc-types-admin/CHANGELOG.md +++ b/crates/rpc-types-admin/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 ### Bug Fixes @@ -13,7 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks -- Release 0.2.0 +- Release 0.2.1 +- Chore : fix typos ([#1087](https://github.com/alloy-rs/alloy/issues/1087)) - Release 0.2.0 ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 diff --git a/crates/rpc-types-anvil/CHANGELOG.md b/crates/rpc-types-anvil/CHANGELOG.md index 2d120db226c..85acc1f683f 100644 --- a/crates/rpc-types-anvil/CHANGELOG.md +++ b/crates/rpc-types-anvil/CHANGELOG.md @@ -5,11 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 ### Miscellaneous Tasks -- Release 0.2.0 +- Release 0.2.1 - Release 0.2.0 ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 diff --git a/crates/rpc-types-beacon/CHANGELOG.md b/crates/rpc-types-beacon/CHANGELOG.md index 2f16fd707a6..578219cf9d4 100644 --- a/crates/rpc-types-beacon/CHANGELOG.md +++ b/crates/rpc-types-beacon/CHANGELOG.md @@ -5,11 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 ### Miscellaneous Tasks -- Release 0.2.0 +- Release 0.2.1 - Release 0.2.0 ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 diff --git a/crates/rpc-types-engine/CHANGELOG.md b/crates/rpc-types-engine/CHANGELOG.md index 349a15fd96f..d7b2b80c814 100644 --- a/crates/rpc-types-engine/CHANGELOG.md +++ b/crates/rpc-types-engine/CHANGELOG.md @@ -5,11 +5,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 + +### Dependencies + +- Bump jsonrpsee 0.24 ([#1067](https://github.com/alloy-rs/alloy/issues/1067)) + +### Features + +- [engine-types] `PayloadError::PrePragueBlockWithEip7702Transactions` ([#1116](https://github.com/alloy-rs/alloy/issues/1116)) ### Miscellaneous Tasks -- Release 0.2.0 +- Release 0.2.1 - Release 0.2.0 - Add payloadbodies v2 to capabilities set ([#1025](https://github.com/alloy-rs/alloy/issues/1025)) diff --git a/crates/rpc-types-eth/CHANGELOG.md b/crates/rpc-types-eth/CHANGELOG.md index 85720423448..132541f26d3 100644 --- a/crates/rpc-types-eth/CHANGELOG.md +++ b/crates/rpc-types-eth/CHANGELOG.md @@ -5,25 +5,41 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 ### Bug Fixes - Trim conflicting key `max_fee_per_blob_gas` from Eip1559 tx type ([#1064](https://github.com/alloy-rs/alloy/issues/1064)) +### Dependencies + +- Bump jsonrpsee 0.24 ([#1067](https://github.com/alloy-rs/alloy/issues/1067)) + ### Features +- Eth_simulateV1 Request / Response types ([#1042](https://github.com/alloy-rs/alloy/issues/1042)) +- Feat(rpc-type-eth) convert vec TxReq to bundle ([#1091](https://github.com/alloy-rs/alloy/issues/1091)) +- Feat(provider) : introduction to eth_sendRawTransactionConditional RPC endpoint type ([#1009](https://github.com/alloy-rs/alloy/issues/1009)) - [rpc-types-eth] Serde flatten `BlobTransactionSidecar` in tx req ([#1054](https://github.com/alloy-rs/alloy/issues/1054)) - Add authorization list to rpc transaction and tx receipt types ([#1051](https://github.com/alloy-rs/alloy/issues/1051)) ### Miscellaneous Tasks -- Release 0.2.0 +- Release 0.2.1 +- [rpc] Make `Deserialize` impl for `FilterChanges` generic over transaction ([#1118](https://github.com/alloy-rs/alloy/issues/1118)) +- Export rpc account type ([#1075](https://github.com/alloy-rs/alloy/issues/1075)) - Release 0.2.0 - Fix unnameable types ([#1029](https://github.com/alloy-rs/alloy/issues/1029)) +### Other + +- Add `AccessListResult` type (EIP-2930) ([#1110](https://github.com/alloy-rs/alloy/issues/1110)) +- Derive arbitrary for `TransactionRequest` ([#1113](https://github.com/alloy-rs/alloy/issues/1113)) +- Added stages to the sync info rpc type ([#1079](https://github.com/alloy-rs/alloy/issues/1079)) + ### Refactor +- Add network-primitives ([#1101](https://github.com/alloy-rs/alloy/issues/1101)) - Replace `U64` with `u64` ([#1057](https://github.com/alloy-rs/alloy/issues/1057)) ### Styling diff --git a/crates/rpc-types-mev/CHANGELOG.md b/crates/rpc-types-mev/CHANGELOG.md index f1c0bc3a696..46c273218aa 100644 --- a/crates/rpc-types-mev/CHANGELOG.md +++ b/crates/rpc-types-mev/CHANGELOG.md @@ -5,11 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 ### Miscellaneous Tasks -- Release 0.2.0 +- Release 0.2.1 +- Chore : fix typos ([#1087](https://github.com/alloy-rs/alloy/issues/1087)) - Release 0.2.0 ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 diff --git a/crates/rpc-types-trace/CHANGELOG.md b/crates/rpc-types-trace/CHANGELOG.md index f7b1b92a24e..bb2dea7d1cb 100644 --- a/crates/rpc-types-trace/CHANGELOG.md +++ b/crates/rpc-types-trace/CHANGELOG.md @@ -5,15 +5,21 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 + +### Bug Fixes + +- Make Parity TraceResults output optional ([#1102](https://github.com/alloy-rs/alloy/issues/1102)) ### Features +- [rpc/trace] Filter matches with trace ([#1090](https://github.com/alloy-rs/alloy/issues/1090)) - [otterscan] Add ots slim block and serialze OperationType to int ([#1043](https://github.com/alloy-rs/alloy/issues/1043)) ### Miscellaneous Tasks -- Release 0.2.0 +- Release 0.2.1 +- Chore : fix typos ([#1087](https://github.com/alloy-rs/alloy/issues/1087)) - Release 0.2.0 - Trace output utils ([#1027](https://github.com/alloy-rs/alloy/issues/1027)) diff --git a/crates/rpc-types-txpool/CHANGELOG.md b/crates/rpc-types-txpool/CHANGELOG.md index 34c1bd210a1..323beaef1a5 100644 --- a/crates/rpc-types-txpool/CHANGELOG.md +++ b/crates/rpc-types-txpool/CHANGELOG.md @@ -5,11 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 ### Miscellaneous Tasks -- Release 0.2.0 +- Release 0.2.1 - Release 0.2.0 ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 diff --git a/crates/rpc-types/CHANGELOG.md b/crates/rpc-types/CHANGELOG.md index aff7a29039a..5e26c7bbc87 100644 --- a/crates/rpc-types/CHANGELOG.md +++ b/crates/rpc-types/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 ### Features @@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks -- Release 0.2.0 +- Release 0.2.1 - Release 0.2.0 ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 diff --git a/crates/serde/CHANGELOG.md b/crates/serde/CHANGELOG.md index 9897d637c17..13c026688e5 100644 --- a/crates/serde/CHANGELOG.md +++ b/crates/serde/CHANGELOG.md @@ -5,10 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 ### Miscellaneous Tasks +- Release 0.2.0 - Fix unnameable types ([#1029](https://github.com/alloy-rs/alloy/issues/1029)) ### Styling diff --git a/crates/signer-aws/CHANGELOG.md b/crates/signer-aws/CHANGELOG.md index 8d0a305c90b..caba9a2484a 100644 --- a/crates/signer-aws/CHANGELOG.md +++ b/crates/signer-aws/CHANGELOG.md @@ -5,11 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 ### Miscellaneous Tasks -- Release 0.2.0 +- Release 0.2.1 - Release 0.2.0 ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 diff --git a/crates/signer-gcp/CHANGELOG.md b/crates/signer-gcp/CHANGELOG.md index fe18142eb7d..ecbbe7af20e 100644 --- a/crates/signer-gcp/CHANGELOG.md +++ b/crates/signer-gcp/CHANGELOG.md @@ -5,11 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 ### Miscellaneous Tasks -- Release 0.2.0 +- Release 0.2.1 - Release 0.2.0 ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 diff --git a/crates/signer-ledger/CHANGELOG.md b/crates/signer-ledger/CHANGELOG.md index aeb71f23047..9ade16f4cfa 100644 --- a/crates/signer-ledger/CHANGELOG.md +++ b/crates/signer-ledger/CHANGELOG.md @@ -5,11 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 ### Miscellaneous Tasks -- Release 0.2.0 +- Release 0.2.1 - Release 0.2.0 ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 diff --git a/crates/signer-local/CHANGELOG.md b/crates/signer-local/CHANGELOG.md index defe425da03..1c50597d862 100644 --- a/crates/signer-local/CHANGELOG.md +++ b/crates/signer-local/CHANGELOG.md @@ -5,11 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 ### Miscellaneous Tasks -- Release 0.2.0 +- Release 0.2.1 - Release 0.2.0 - Fix unnameable types ([#1029](https://github.com/alloy-rs/alloy/issues/1029)) diff --git a/crates/signer-trezor/CHANGELOG.md b/crates/signer-trezor/CHANGELOG.md index e8df4185f60..ee5bd9f5816 100644 --- a/crates/signer-trezor/CHANGELOG.md +++ b/crates/signer-trezor/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 ### Dependencies @@ -13,7 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks -- Release 0.2.0 +- Release 0.2.1 - Release 0.2.0 ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 diff --git a/crates/signer/CHANGELOG.md b/crates/signer/CHANGELOG.md index ca994bf36f9..0b51a2e155a 100644 --- a/crates/signer/CHANGELOG.md +++ b/crates/signer/CHANGELOG.md @@ -5,11 +5,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 + +### Features + +- Use EncodableSignature for tx encoding ([#1100](https://github.com/alloy-rs/alloy/issues/1100)) ### Miscellaneous Tasks -- Release 0.2.0 +- Release 0.2.1 - Release 0.2.0 ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 diff --git a/crates/transport-http/CHANGELOG.md b/crates/transport-http/CHANGELOG.md index 146c016b946..fa45af65000 100644 --- a/crates/transport-http/CHANGELOG.md +++ b/crates/transport-http/CHANGELOG.md @@ -5,11 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 ### Miscellaneous Tasks -- Release 0.2.0 +- Release 0.2.1 - Release 0.2.0 ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 diff --git a/crates/transport-ipc/CHANGELOG.md b/crates/transport-ipc/CHANGELOG.md index edbae0d18dc..b28867b1dea 100644 --- a/crates/transport-ipc/CHANGELOG.md +++ b/crates/transport-ipc/CHANGELOG.md @@ -5,11 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 ### Miscellaneous Tasks -- Release 0.2.0 +- Release 0.2.1 - Release 0.2.0 ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 diff --git a/crates/transport-ws/CHANGELOG.md b/crates/transport-ws/CHANGELOG.md index 59b028483d8..2b673021b7d 100644 --- a/crates/transport-ws/CHANGELOG.md +++ b/crates/transport-ws/CHANGELOG.md @@ -5,11 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 ### Miscellaneous Tasks -- Release 0.2.0 +- Release 0.2.1 - Release 0.2.0 ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 diff --git a/crates/transport/CHANGELOG.md b/crates/transport/CHANGELOG.md index e1b248fc7b2..f9107b3a8e2 100644 --- a/crates/transport/CHANGELOG.md +++ b/crates/transport/CHANGELOG.md @@ -5,11 +5,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.0](https://github.com/alloy-rs/alloy/releases/tag/v0.2.0) - 2024-07-16 +## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 + +### Documentation + +- Update links to use docs.rs ([#1066](https://github.com/alloy-rs/alloy/issues/1066)) + +### Features + +- Enable more features transitively in meta crate ([#1097](https://github.com/alloy-rs/alloy/issues/1097)) ### Miscellaneous Tasks -- Release 0.2.0 +- Release 0.2.1 - Release 0.2.0 - Fix unnameable types ([#1029](https://github.com/alloy-rs/alloy/issues/1029)) From d3702713b94809b772c39f635e8fcdb89b796530 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Mon, 5 Aug 2024 10:39:14 +0200 Subject: [PATCH 061/186] Make `alloy_rpc_types_eth::SubscriptionResult` generic over tx (#1123) Make alloy_rpc_types_eth::SubscriptionResult generic over tx --- crates/rpc-types-eth/src/pubsub.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/crates/rpc-types-eth/src/pubsub.rs b/crates/rpc-types-eth/src/pubsub.rs index da8f41563c5..d4417954a2d 100644 --- a/crates/rpc-types-eth/src/pubsub.rs +++ b/crates/rpc-types-eth/src/pubsub.rs @@ -7,7 +7,7 @@ use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer}; /// Subscription result. #[derive(Clone, Debug, PartialEq, Eq, Deserialize)] #[serde(untagged)] -pub enum SubscriptionResult { +pub enum SubscriptionResult { /// New block header. Header(Box), /// Log @@ -15,7 +15,7 @@ pub enum SubscriptionResult { /// Transaction hash TransactionHash(B256), /// Full Transaction - FullTransaction(Box), + FullTransaction(Box), /// SyncStatus SyncState(PubSubSyncStatus), } @@ -45,7 +45,10 @@ pub struct SyncStatusMetadata { pub highest_block: Option, } -impl Serialize for SubscriptionResult { +impl Serialize for SubscriptionResult +where + T: Serialize, +{ fn serialize(&self, serializer: S) -> Result where S: Serializer, From 35e170d1a7f3b802b566908c22eca05c96d921ba Mon Sep 17 00:00:00 2001 From: tesseract <146037313+DoTheBestToGetTheBest@users.noreply.github.com> Date: Mon, 5 Aug 2024 12:02:44 -0700 Subject: [PATCH 062/186] feat: add authorization list to TransactionRequest (#1125) * Update request.rs * Update mod.rs * add list --- crates/rpc-types-eth/src/transaction/mod.rs | 1 + crates/rpc-types-eth/src/transaction/request.rs | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/crates/rpc-types-eth/src/transaction/mod.rs b/crates/rpc-types-eth/src/transaction/mod.rs index c81ecf414e7..809374ab6bb 100644 --- a/crates/rpc-types-eth/src/transaction/mod.rs +++ b/crates/rpc-types-eth/src/transaction/mod.rs @@ -158,6 +158,7 @@ impl Transaction { max_fee_per_blob_gas: self.max_fee_per_blob_gas, blob_versioned_hashes: self.blob_versioned_hashes, sidecar: None, + authorization_list: None, } } } diff --git a/crates/rpc-types-eth/src/transaction/request.rs b/crates/rpc-types-eth/src/transaction/request.rs index b61d2875cfb..2a31755b880 100644 --- a/crates/rpc-types-eth/src/transaction/request.rs +++ b/crates/rpc-types-eth/src/transaction/request.rs @@ -5,6 +5,7 @@ use alloy_consensus::{ TxEip1559, TxEip2930, TxEip4844, TxEip4844Variant, TxEip4844WithSidecar, TxEnvelope, TxLegacy, TxType, TypedTransaction, }; +use alloy_eips::eip7702::SignedAuthorization; use alloy_primitives::{Address, Bytes, ChainId, TxKind, B256, U256}; use serde::{Deserialize, Serialize}; use std::hash::Hash; @@ -66,6 +67,9 @@ pub struct TransactionRequest { /// Blob sidecar for EIP-4844 transactions. #[serde(default, flatten, skip_serializing_if = "Option::is_none")] pub sidecar: Option, + /// Authorization list for for 7702 transactions. + #[serde(default, flatten, skip_serializing_if = "Option::is_none")] + pub authorization_list: Option>, } impl TransactionRequest { From 68c8bfc2b786e6e460475b28e0f2453bbcf90e55 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Mon, 5 Aug 2024 22:03:49 +0200 Subject: [PATCH 063/186] Add conversion from BlockHashOrNumber to BlockId (#1127) --- crates/eips/src/eip1898.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/crates/eips/src/eip1898.rs b/crates/eips/src/eip1898.rs index ca19ef64907..4d1544a0bab 100644 --- a/crates/eips/src/eip1898.rs +++ b/crates/eips/src/eip1898.rs @@ -385,6 +385,17 @@ impl From for BlockId { } } +impl From for BlockId { + fn from(block: BlockHashOrNumber) -> Self { + match block { + BlockHashOrNumber::Hash(hash) => { + Self::Hash(RpcBlockHash { block_hash: hash, require_canonical: None }) + } + BlockHashOrNumber::Number(num) => Self::Number(BlockNumberOrTag::Number(num)), + } + } +} + impl From for BlockId { fn from(block_hash: B256) -> Self { Self::Hash(RpcBlockHash { block_hash, require_canonical: None }) From 512c8ad256708a3173485b9f76c59c1cf4373b87 Mon Sep 17 00:00:00 2001 From: cui <523516579@qq.com> Date: Tue, 6 Aug 2024 23:38:44 +0800 Subject: [PATCH 064/186] fix(rpc): show data in when cast send result in custom error (#1129) * fix(rpc): show data in when cast send result in custom error * fix: remove Clone and Default trait * fix: testcases failed * fix: clippy and fmt --- crates/json-rpc/src/response/error.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/crates/json-rpc/src/response/error.rs b/crates/json-rpc/src/response/error.rs index edf94315d26..0d318837059 100644 --- a/crates/json-rpc/src/response/error.rs +++ b/crates/json-rpc/src/response/error.rs @@ -81,9 +81,15 @@ fn spelunk_revert(value: &Value) -> Option { } } -impl fmt::Display for ErrorPayload { +impl fmt::Display for ErrorPayload { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "error code {}: {}", self.code, self.message) + write!( + f, + "error code {}: {}{}", + self.code, + self.message, + self.data.as_ref().map(|data| format!(", data: {}", data)).unwrap_or_default() + ) } } From 0c998d3300f73451e1985698bf68a61db2b4ee54 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 6 Aug 2024 22:08:10 +0200 Subject: [PATCH 065/186] chore(dep): feature gate jwt in engine types (#1131) * chore(dep): feature gate jwt in engine types * rm rand --- crates/rpc-types-engine/Cargo.toml | 6 ++++-- crates/rpc-types-engine/src/lib.rs | 6 +++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/crates/rpc-types-engine/Cargo.toml b/crates/rpc-types-engine/Cargo.toml index dbc30871e26..48d3c4332d8 100644 --- a/crates/rpc-types-engine/Cargo.toml +++ b/crates/rpc-types-engine/Cargo.toml @@ -38,10 +38,12 @@ thiserror.workspace = true jsonrpsee-types = { version = "0.24", optional = true } # jwt -jsonwebtoken = "9.3.0" -rand.workspace = true +jsonwebtoken = { version = "9.3.0", optional = true } +rand = { workspace = true, optional = true } [features] +default = ["jwt"] +jwt = ["dep:jsonwebtoken", "dep:rand"] jsonrpsee-types = ["dep:jsonrpsee-types"] ssz = [ "dep:ethereum_ssz", diff --git a/crates/rpc-types-engine/src/lib.rs b/crates/rpc-types-engine/src/lib.rs index 4e5b9c52fea..a8ef6b7a6d1 100644 --- a/crates/rpc-types-engine/src/lib.rs +++ b/crates/rpc-types-engine/src/lib.rs @@ -9,15 +9,19 @@ mod cancun; mod forkchoice; mod identification; +#[cfg(feature = "jwt")] mod jwt; mod optimism; pub mod payload; mod transition; pub use self::{ - cancun::*, forkchoice::*, identification::*, jwt::*, optimism::*, payload::*, transition::*, + cancun::*, forkchoice::*, identification::*, optimism::*, payload::*, transition::*, }; +#[cfg(feature = "jwt")] +pub use self::jwt::*; + #[doc(inline)] pub use alloy_eips::eip6110::DepositRequest as DepositRequestV1; From c3ccf7e2c5f9720fa6c193a9ea918aabf88aa6a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dino=20Pa=C4=8Dandi?= <3002868+Dinonard@users.noreply.github.com> Date: Wed, 7 Aug 2024 13:02:55 +0200 Subject: [PATCH 066/186] TxRequest into EIP-4844 without sidecar (#1093) * TxReq into Eip4844 without sidecar * Formatting * Minor comments * Address review comments * Address review comments * Remove comment * Review comments --- crates/rpc-types-eth/Cargo.toml | 1 + .../rpc-types-eth/src/transaction/request.rs | 362 +++++++++++++++--- 2 files changed, 300 insertions(+), 63 deletions(-) diff --git a/crates/rpc-types-eth/Cargo.toml b/crates/rpc-types-eth/Cargo.toml index 60d2bc135ab..bc4c7ebb203 100644 --- a/crates/rpc-types-eth/Cargo.toml +++ b/crates/rpc-types-eth/Cargo.toml @@ -53,6 +53,7 @@ alloy-eips = { workspace = true, features = ["arbitrary", "k256"] } arbitrary = { workspace = true, features = ["derive"] } rand.workspace = true similar-asserts.workspace = true +assert_matches.workspace = true [features] arbitrary = [ diff --git a/crates/rpc-types-eth/src/transaction/request.rs b/crates/rpc-types-eth/src/transaction/request.rs index 2a31755b880..8061ab5b899 100644 --- a/crates/rpc-types-eth/src/transaction/request.rs +++ b/crates/rpc-types-eth/src/transaction/request.rs @@ -184,104 +184,125 @@ impl TransactionRequest { /// Build a legacy transaction. /// - /// # Panics - /// - /// If required fields are missing. Use `complete_legacy` to check if the - /// request can be built. - fn build_legacy(self) -> TxLegacy { - let checked_to = self.to.expect("checked in complete_legacy."); + /// Returns an error if required fields are missing. + /// Use `complete_legacy` to check if the request can be built. + fn build_legacy(self) -> Result { + let checked_to = self.to.ok_or("Missing 'to' field for legacy transaction.")?; - TxLegacy { + Ok(TxLegacy { chain_id: self.chain_id, - nonce: self.nonce.expect("checked in complete_legacy"), - gas_price: self.gas_price.expect("checked in complete_legacy"), - gas_limit: self.gas.expect("checked in complete_legacy"), + nonce: self.nonce.ok_or("Missing 'nonce' field for legacy transaction.")?, + gas_price: self.gas_price.ok_or("Missing 'gas_price' for legacy transaction.")?, + gas_limit: self.gas.ok_or("Missing 'gas_limit' for legacy transaction.")?, to: checked_to, value: self.value.unwrap_or_default(), input: self.input.into_input().unwrap_or_default(), - } + }) } /// Build an EIP-1559 transaction. /// - /// # Panics - /// - /// If required fields are missing. Use `complete_1559` to check if the + /// Returns ane error if required fields are missing. Use `complete_1559` to check if the /// request can be built. - fn build_1559(self) -> TxEip1559 { - let checked_to = self.to.expect("checked in complete_1559."); + fn build_1559(self) -> Result { + let checked_to = self.to.ok_or("Missing 'to' field for Eip1559 transaction.")?; - TxEip1559 { + Ok(TxEip1559 { chain_id: self.chain_id.unwrap_or(1), - nonce: self.nonce.expect("checked in invalid_common_fields"), + nonce: self.nonce.ok_or("Missing 'nonce' field for Eip1559 transaction.")?, max_priority_fee_per_gas: self .max_priority_fee_per_gas - .expect("checked in invalid_1559_fields"), - max_fee_per_gas: self.max_fee_per_gas.expect("checked in invalid_1559_fields"), - gas_limit: self.gas.expect("checked in invalid_common_fields"), + .ok_or("Missing 'max_priority_fee_per_gas' field for Eip1559 transaction.")?, + max_fee_per_gas: self + .max_fee_per_gas + .ok_or("Missing 'max_fee_per_gas' field for Eip1559 transaction.")?, + gas_limit: self.gas.ok_or("Missing 'gas_limit' field for Eip1559 transaction.")?, to: checked_to, value: self.value.unwrap_or_default(), input: self.input.into_input().unwrap_or_default(), access_list: self.access_list.unwrap_or_default(), - } + }) } /// Build an EIP-2930 transaction. /// - /// # Panics - /// - /// If required fields are missing. Use `complete_2930` to check if the + /// Returns an error if required fields are missing. Use `complete_2930` to check if the /// request can be built. - fn build_2930(self) -> TxEip2930 { - let checked_to = self.to.expect("checked in complete_2930."); + fn build_2930(self) -> Result { + let checked_to = self.to.ok_or("Missing 'to' field for Eip2930 transaction.")?; - TxEip2930 { + Ok(TxEip2930 { chain_id: self.chain_id.unwrap_or(1), - nonce: self.nonce.expect("checked in complete_2930"), - gas_price: self.gas_price.expect("checked in complete_2930"), - gas_limit: self.gas.expect("checked in complete_2930"), + nonce: self.nonce.ok_or("Missing 'nonce' field for Eip2930 transaction.")?, + gas_price: self + .gas_price + .ok_or("Missing 'gas_price' field for Eip2930 transaction.")?, + gas_limit: self.gas.ok_or("Missing 'gas_limit' field for Eip2930 transaction.")?, to: checked_to, value: self.value.unwrap_or_default(), input: self.input.into_input().unwrap_or_default(), access_list: self.access_list.unwrap_or_default(), - } + }) } - /// Build an EIP-4844 transaction. + /// Build an EIP-4844 transaction variant - either with or without sidecar. /// - /// # Panics + /// Returns an error if required fields are missing. Use `complete_4844` to check if the + /// request can be built. + fn build_4844_variant(self) -> Result { + if self.sidecar.is_none() { + self.build_4844_without_sidecar().map(Into::into) + } else { + self.build_4844_with_sidecar().map(Into::into) + } + } + + /// Build an EIP-4844 transaction without sidecar. /// - /// If required fields are missing. Use `complete_4844` to check if the + /// Returns an error if required fields are missing. Use `complete_4844` to check if the /// request can be built. - fn build_4844(mut self) -> TxEip4844WithSidecar { - self.populate_blob_hashes(); + fn build_4844_without_sidecar(self) -> Result { + let checked_to = self.to.ok_or("Missing 'to' field for Eip4844 transaction.")?; - let checked_to = self.to.expect("checked in complete_4844."); let to_address = match checked_to { - TxKind::Create => panic!("the field `to` can only be of type TxKind::Call(Account). Please change it accordingly."), + TxKind::Create => return Err("The field `to` can only be of type TxKind::Call(Account). Please change it accordingly."), TxKind::Call(to) => to, }; - TxEip4844WithSidecar { - sidecar: self.sidecar.expect("checked in complete_4844"), - tx: TxEip4844 { - chain_id: self.chain_id.unwrap_or(1), - nonce: self.nonce.expect("checked in complete_4844"), - gas_limit: self.gas.expect("checked in complete_4844"), - max_fee_per_gas: self.max_fee_per_gas.expect("checked in complete_4844"), - max_priority_fee_per_gas: self - .max_priority_fee_per_gas - .expect("checked in complete_4844"), - to: to_address, - value: self.value.unwrap_or_default(), - access_list: self.access_list.unwrap_or_default(), - blob_versioned_hashes: self - .blob_versioned_hashes - .expect("populated at top of block"), - max_fee_per_blob_gas: self.max_fee_per_blob_gas.expect("checked in complete_4844"), - input: self.input.into_input().unwrap_or_default(), - }, - } + Ok(TxEip4844 { + chain_id: self.chain_id.unwrap_or(1), + nonce: self.nonce.ok_or("Missing 'nonce' field for Eip4844 transaction.")?, + gas_limit: self.gas.ok_or("Missing 'gas_limit' field for Eip4844 transaction.")?, + max_fee_per_gas: self + .max_fee_per_gas + .ok_or("Missing 'max_fee_per_gas' field for Eip4844 transaction.")?, + max_priority_fee_per_gas: self + .max_priority_fee_per_gas + .ok_or("Missing 'max_priority_fee_per_gas' field for Eip4844 transaction.")?, + to: to_address, + value: self.value.unwrap_or_default(), + access_list: self.access_list.unwrap_or_default(), + blob_versioned_hashes: self + .blob_versioned_hashes + .ok_or("Missing 'blob_versioned_hashes' field for Eip4844 transaction.")?, + max_fee_per_blob_gas: self + .max_fee_per_blob_gas + .ok_or("Missing 'max_fee_per_blob_gas' field for Eip4844 transaction.")?, + input: self.input.into_input().unwrap_or_default(), + }) + } + + /// Build an EIP-4844 transaction with sidecar. + /// + /// Returns an error if required fields are missing. Use `complete_4844` to check if the + /// request can be built. + fn build_4844_with_sidecar(mut self) -> Result { + self.populate_blob_hashes(); + + let sidecar = + self.sidecar.clone().ok_or("Missing 'sidecar' field for Eip4844 transaction.")?; + + Ok(TxEip4844WithSidecar { sidecar, tx: self.build_4844_without_sidecar()? }) } fn check_reqd_fields(&self) -> Vec<&'static str> { @@ -388,6 +409,8 @@ impl TransactionRequest { /// Check if all necessary keys are present to build a 4844 transaction, /// returning a list of keys that are missing. + /// + /// **NOTE:** `sidecar` must be present, even if `blob_versioned_hashes` is set. pub fn complete_4844(&self) -> Result<(), Vec<&'static str>> { let mut missing = self.check_reqd_fields(); self.check_1559_fields(&mut missing); @@ -467,6 +490,9 @@ impl TransactionRequest { } /// Build an [`TypedTransaction`] + /// + /// In case `Ok(...)` is returned, the `TypedTransaction` is guaranteed to be _complete_, e.g. + /// sendable to the network. pub fn build_typed_tx(self) -> Result { let tx_type = self.buildable_type(); @@ -475,12 +501,38 @@ impl TransactionRequest { } Ok(match tx_type.expect("checked") { - TxType::Legacy => self.build_legacy().into(), - TxType::Eip2930 => self.build_2930().into(), - TxType::Eip1559 => self.build_1559().into(), - TxType::Eip4844 => self.build_4844().into(), + TxType::Legacy => self.build_legacy().expect("checked)").into(), + TxType::Eip2930 => self.build_2930().expect("checked)").into(), + TxType::Eip1559 => self.build_1559().expect("checked)").into(), + // `sidecar` is a hard requirement since this must be a _sendable_ transaction. + TxType::Eip4844 => self.build_4844_with_sidecar().expect("checked)").into(), }) } + + /// Build an [`TypedTransaction`]. + /// + /// In case `Ok(...)` is returned, the `TypedTransaction` does not guarantee to be _complete_, + /// e.g. sendable to the network. + /// + /// E.g. a particular case is when the transaction is of type `Eip4844` and the `sidecar` is not + /// set, in this case the transaction is not _complete_. It can still be used to calculate the + /// signature of the transaction though. + /// + /// In case the requirement is to build a _complete_ transaction, use `build_typed_tx` instead. + pub fn build_consensus_tx(self) -> Result { + match self.preferred_type() { + TxType::Legacy => self.clone().build_legacy().map(Into::into), + TxType::Eip2930 => self.clone().build_2930().map(Into::into), + TxType::Eip1559 => self.clone().build_1559().map(Into::into), + TxType::Eip4844 => self.clone().build_4844_variant().map(Into::into), + } + .map_err(|msg| self.into_tx_err(msg)) + } + + /// Converts the transaction request into a `BuildTransactionErr` with the given message. + fn into_tx_err(self, message: &'static str) -> BuildTransactionErr { + BuildTransactionErr { tx: self, error: message.to_string() } + } } /// Helper type that supports both `data` and `input` fields that map to transaction input data. @@ -786,11 +838,21 @@ impl From for TransactionRequest { #[non_exhaustive] pub struct TransactionInputError; +/// Error thrown when a transaction request cannot be built into a transaction. +#[derive(Debug)] +pub struct BuildTransactionErr { + /// Transaction request that failed to build into a transaction. + pub tx: TransactionRequest, + /// Error message. + pub error: String, +} + #[cfg(test)] mod tests { use super::*; use alloy_primitives::b256; use alloy_serde::WithOtherFields; + use assert_matches::assert_matches; // #[test] @@ -907,4 +969,178 @@ mod tests { assert!(req.sidecar.is_none()); // Sidecar won't be deserialized. } + + #[test] + fn build_consensus_tx_works() { + // Legacy + { + // Positive case + let legacy_gas_limit = 123456; + let legacy_request: TransactionRequest = TransactionRequest { + to: Some(TxKind::Call(Address::repeat_byte(0xDE))), + gas_price: Some(1234), + nonce: Some(57), + gas: Some(legacy_gas_limit), + ..Default::default() + }; + + let maybe_legacy_tx: Result = legacy_request.build_consensus_tx(); + assert_matches!(maybe_legacy_tx, Ok(TypedTransaction::Legacy(TxLegacy { gas_limit, .. })) if gas_limit == legacy_gas_limit); + + // Negative case + let legacy_request_missing_gas: TransactionRequest = TransactionRequest { + to: Some(TxKind::Call(Address::repeat_byte(0xDE))), + gas_price: Some(1234), + nonce: Some(57), + ..Default::default() + }; + let maybe_legacy_tx: Result = + legacy_request_missing_gas.build_consensus_tx(); + assert_matches!(maybe_legacy_tx, Err(..)); + } + + // EIP-2930 + { + // Positive case + let access_list = AccessList(vec![alloy_eips::eip2930::AccessListItem { + address: Address::repeat_byte(0x01), + storage_keys: vec![B256::repeat_byte(0x02), B256::repeat_byte(0x04)], + }]); + let eip2930_request: TransactionRequest = TransactionRequest { + to: Some(TxKind::Call(Address::repeat_byte(0xDE))), + gas_price: Some(1234), + nonce: Some(57), + gas: Some(123456), + access_list: Some(access_list.clone()), + ..Default::default() + }; + + let maybe_eip2930_tx: Result = + eip2930_request.build_consensus_tx(); + assert_matches!(maybe_eip2930_tx, Ok(TypedTransaction::Eip2930(TxEip2930 { access_list, .. })) if access_list == access_list); + + // Negative case + let eip2930_request_missing_nonce: TransactionRequest = TransactionRequest { + to: Some(TxKind::Call(Address::repeat_byte(0xDE))), + gas_price: Some(1234), + gas: Some(123456), + access_list: Some(access_list), + ..Default::default() + }; + + let maybe_eip2930_tx: Result = + eip2930_request_missing_nonce.build_consensus_tx(); + assert_matches!(maybe_eip2930_tx, Err(..)); + } + + // EIP-1559 + { + // Positive case + let max_prio_fee = 987; + let eip1559_request: TransactionRequest = TransactionRequest { + to: Some(TxKind::Call(Address::repeat_byte(0xDE))), + max_fee_per_gas: Some(1234), + max_priority_fee_per_gas: Some(max_prio_fee), + nonce: Some(57), + gas: Some(123456), + ..Default::default() + }; + + let maybe_eip1559_tx: Result = + eip1559_request.build_consensus_tx(); + assert_matches!(maybe_eip1559_tx, Ok(TypedTransaction::Eip1559(TxEip1559 { max_priority_fee_per_gas, .. })) if max_priority_fee_per_gas == max_prio_fee); + + // Negative case + let eip1559_request_missing_max_fee: TransactionRequest = TransactionRequest { + to: Some(TxKind::Call(Address::repeat_byte(0xDE))), + max_priority_fee_per_gas: Some(max_prio_fee), + nonce: Some(57), + gas: Some(123456), + ..Default::default() + }; + + let maybe_eip1559_tx: Result = + eip1559_request_missing_max_fee.build_consensus_tx(); + assert_matches!(maybe_eip1559_tx, Err(..)); + } + + // EIP-4844 without sidecar + { + // Positive case + let max_fee_per_blob_gas = 13579; + let eip4844_request: TransactionRequest = TransactionRequest { + to: Some(TxKind::Call(Address::repeat_byte(0xDE))), + max_fee_per_gas: Some(1234), + max_priority_fee_per_gas: Some(678), + nonce: Some(57), + gas: Some(123456), + max_fee_per_blob_gas: Some(max_fee_per_blob_gas), + blob_versioned_hashes: Some(vec![B256::repeat_byte(0xAB)]), + ..Default::default() + }; + + let maybe_eip4844_tx: Result = + eip4844_request.build_consensus_tx(); + assert_matches!(maybe_eip4844_tx, Ok(TypedTransaction::Eip4844(TxEip4844Variant::TxEip4844(TxEip4844 { max_fee_per_blob_gas, .. }))) if max_fee_per_blob_gas == max_fee_per_blob_gas); + + // Negative case + let eip4844_request_incorrect_to: TransactionRequest = TransactionRequest { + to: Some(TxKind::Create), + max_fee_per_gas: Some(1234), + max_priority_fee_per_gas: Some(678), + nonce: Some(57), + gas: Some(123456), + max_fee_per_blob_gas: Some(max_fee_per_blob_gas), + blob_versioned_hashes: Some(vec![B256::repeat_byte(0xAB)]), + ..Default::default() + }; + + let maybe_eip4844_tx: Result = + eip4844_request_incorrect_to.build_consensus_tx(); + assert_matches!(maybe_eip4844_tx, Err(..)); + } + + // EIP-4844 with sidecar + { + use alloy_eips::eip4844::{Blob, BlobTransactionSidecar}; + + // Positive case + let sidecar = + BlobTransactionSidecar::new(vec![Blob::repeat_byte(0xFA)], Vec::new(), Vec::new()); + let eip4844_request: TransactionRequest = TransactionRequest { + to: Some(TxKind::Call(Address::repeat_byte(0xDE))), + max_fee_per_gas: Some(1234), + max_priority_fee_per_gas: Some(678), + nonce: Some(57), + gas: Some(123456), + max_fee_per_blob_gas: Some(13579), + blob_versioned_hashes: Some(vec![B256::repeat_byte(0xAB)]), + sidecar: Some(sidecar.clone()), + ..Default::default() + }; + + let maybe_eip4844_tx: Result = + eip4844_request.build_consensus_tx(); + assert_matches!(maybe_eip4844_tx, + Ok(TypedTransaction::Eip4844(TxEip4844Variant::TxEip4844WithSidecar(TxEip4844WithSidecar { + sidecar, .. }))) if sidecar == sidecar); + + // Negative case + let eip4844_request_incorrect_to: TransactionRequest = TransactionRequest { + to: Some(TxKind::Create), + max_fee_per_gas: Some(1234), + max_priority_fee_per_gas: Some(678), + nonce: Some(57), + gas: Some(123456), + max_fee_per_blob_gas: Some(13579), + blob_versioned_hashes: Some(vec![B256::repeat_byte(0xAB)]), + sidecar: Some(sidecar), + ..Default::default() + }; + + let maybe_eip4844_tx: Result = + eip4844_request_incorrect_to.build_consensus_tx(); + assert_matches!(maybe_eip4844_tx, Err(..)); + } + } } From 1e6faaa58cbb1a02286f42c1966bfeefb8dd5ac5 Mon Sep 17 00:00:00 2001 From: zerosnacks <95942363+zerosnacks@users.noreply.github.com> Date: Thu, 8 Aug 2024 12:58:15 +0200 Subject: [PATCH 067/186] fix: use `BlockId` superset over `BlockNumberOrTag` where applicable (#1135) * fix getBlockReceipts to use BlockId * use BlockId where Reth implements it * fix clippy issues * add additional flag to matrix to enable all features as `trace` and `debug` were not being tested * fix doc link * temporarily disable specific failing tests on Windows, to open a ticket to investigate failure cases --- .github/workflows/ci.yml | 2 ++ crates/provider/src/ext/debug.rs | 35 ++++++++++--------- crates/provider/src/ext/trace.rs | 39 ++++++++++------------ crates/provider/src/provider/trait.rs | 15 +++++---- crates/provider/src/provider/with_block.rs | 2 +- crates/rpc-client/src/builtin.rs | 2 +- 6 files changed, 49 insertions(+), 46 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f70cadc95e1..8e4dee9142c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -30,6 +30,8 @@ jobs: - "--no-default-features" # Default features - "" + # All features + - "--all-features" exclude: # All features on MSRV - rust: "1.76" # MSRV diff --git a/crates/provider/src/ext/debug.rs b/crates/provider/src/ext/debug.rs index f8933bff221..d3252972299 100644 --- a/crates/provider/src/ext/debug.rs +++ b/crates/provider/src/ext/debug.rs @@ -2,7 +2,7 @@ use crate::Provider; use alloy_network::Network; use alloy_primitives::{hex, Bytes, TxHash, B256}; -use alloy_rpc_types_eth::{Block, BlockNumberOrTag, TransactionRequest}; +use alloy_rpc_types_eth::{Block, BlockId, BlockNumberOrTag, TransactionRequest}; use alloy_rpc_types_trace::geth::{ BlockTraceResult, GethDebugTracingCallOptions, GethDebugTracingOptions, GethTrace, TraceResult, }; @@ -13,16 +13,16 @@ use alloy_transport::{Transport, TransportResult}; #[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)] pub trait DebugApi: Send + Sync { /// Returns an RLP-encoded header. - async fn debug_get_raw_header(&self, block: BlockNumberOrTag) -> TransportResult; + async fn debug_get_raw_header(&self, block: BlockId) -> TransportResult; /// Retrieves and returns the RLP encoded block by number, hash or tag. - async fn debug_get_raw_block(&self, block: BlockNumberOrTag) -> TransportResult; + async fn debug_get_raw_block(&self, block: BlockId) -> TransportResult; /// Returns an EIP-2718 binary-encoded transaction. async fn debug_get_raw_transaction(&self, hash: TxHash) -> TransportResult; /// Returns an array of EIP-2718 binary-encoded receipts. - async fn debug_get_raw_receipts(&self, block: BlockNumberOrTag) -> TransportResult>; + async fn debug_get_raw_receipts(&self, block: BlockId) -> TransportResult>; /// Returns an array of recent bad blocks that the client has seen on the network. async fn debug_get_bad_blocks(&self) -> TransportResult>; @@ -109,7 +109,7 @@ pub trait DebugApi: Send + Sync { async fn debug_trace_call( &self, tx: TransactionRequest, - block: BlockNumberOrTag, + block: BlockId, trace_options: GethDebugTracingCallOptions, ) -> TransportResult; @@ -123,7 +123,7 @@ pub trait DebugApi: Send + Sync { async fn debug_trace_call_many( &self, txs: Vec, - block: BlockNumberOrTag, + block: BlockId, trace_options: GethDebugTracingCallOptions, ) -> TransportResult>; } @@ -136,11 +136,11 @@ where T: Transport + Clone, P: Provider, { - async fn debug_get_raw_header(&self, block: BlockNumberOrTag) -> TransportResult { + async fn debug_get_raw_header(&self, block: BlockId) -> TransportResult { self.client().request("debug_getRawHeader", (block,)).await } - async fn debug_get_raw_block(&self, block: BlockNumberOrTag) -> TransportResult { + async fn debug_get_raw_block(&self, block: BlockId) -> TransportResult { self.client().request("debug_getRawBlock", (block,)).await } @@ -148,7 +148,7 @@ where self.client().request("debug_getRawTransaction", (hash,)).await } - async fn debug_get_raw_receipts(&self, block: BlockNumberOrTag) -> TransportResult> { + async fn debug_get_raw_receipts(&self, block: BlockId) -> TransportResult> { self.client().request("debug_getRawReceipts", (block,)).await } @@ -200,7 +200,7 @@ where async fn debug_trace_call( &self, tx: TransactionRequest, - block: BlockNumberOrTag, + block: BlockId, trace_options: GethDebugTracingCallOptions, ) -> TransportResult { self.client().request("debug_traceCall", (tx, block, trace_options)).await @@ -209,7 +209,7 @@ where async fn debug_trace_call_many( &self, txs: Vec, - block: BlockNumberOrTag, + block: BlockId, trace_options: GethDebugTracingCallOptions, ) -> TransportResult> { self.client().request("debug_traceCallMany", (txs, block, trace_options)).await @@ -268,7 +268,11 @@ mod test { .max_priority_fee_per_gas(gas_price + 1); let trace = provider - .debug_trace_call(tx, BlockNumberOrTag::Latest, GethDebugTracingCallOptions::default()) + .debug_trace_call( + tx, + BlockNumberOrTag::Latest.into(), + GethDebugTracingCallOptions::default(), + ) .await .unwrap(); @@ -284,7 +288,7 @@ mod test { let provider = ProviderBuilder::new().on_http(geth.endpoint_url()); let rlp_header = provider - .debug_get_raw_header(BlockNumberOrTag::default()) + .debug_get_raw_header(BlockId::Number(BlockNumberOrTag::Latest)) .await .expect("debug_getRawHeader call should succeed"); @@ -298,7 +302,7 @@ mod test { let provider = ProviderBuilder::new().on_http(geth.endpoint_url()); let rlp_block = provider - .debug_get_raw_block(BlockNumberOrTag::default()) + .debug_get_raw_block(BlockId::Number(BlockNumberOrTag::Latest)) .await .expect("debug_getRawBlock call should succeed"); @@ -311,7 +315,8 @@ mod test { let geth = Geth::new().disable_discovery().data_dir(temp_dir.path()).spawn(); let provider = ProviderBuilder::new().on_http(geth.endpoint_url()); - let result = provider.debug_get_raw_receipts(BlockNumberOrTag::default()).await; + let result = + provider.debug_get_raw_receipts(BlockId::Number(BlockNumberOrTag::Latest)).await; assert!(result.is_ok()); } diff --git a/crates/provider/src/ext/trace.rs b/crates/provider/src/ext/trace.rs index 334ef2a883a..b6a81dc2077 100644 --- a/crates/provider/src/ext/trace.rs +++ b/crates/provider/src/ext/trace.rs @@ -1,6 +1,6 @@ //! This module extends the Ethereum JSON-RPC provider with the Trace namespace's RPC methods. use crate::{Provider, RpcWithBlock}; -use alloy_eips::BlockNumberOrTag; +use alloy_eips::BlockId; use alloy_network::Network; use alloy_primitives::TxHash; use alloy_rpc_types_eth::Index; @@ -81,23 +81,20 @@ where /// # Note /// /// Not all nodes support this call. - async fn trace_block( - &self, - block: BlockNumberOrTag, - ) -> TransportResult>; + async fn trace_block(&self, block: BlockId) -> TransportResult>; /// Replays a transaction. async fn trace_replay_transaction( &self, hash: TxHash, - trace_type: &[TraceType], + trace_types: &[TraceType], ) -> TransportResult; /// Replays all transactions in the given block. async fn trace_replay_block_transactions( &self, - block: BlockNumberOrTag, - trace_type: &[TraceType], + block: BlockId, + trace_types: &[TraceType], ) -> TransportResult>; } @@ -112,10 +109,10 @@ where fn trace_call<'a, 'b>( &self, request: &'a ::TransactionRequest, - trace_type: &'b [TraceType], + trace_types: &'b [TraceType], ) -> RpcWithBlock::TransactionRequest, &'b [TraceType]), TraceResults> { - RpcWithBlock::new(self.weak_client(), "trace_call", (request, trace_type)) + RpcWithBlock::new(self.weak_client(), "trace_call", (request, trace_types)) } fn trace_call_many<'a>( @@ -144,9 +141,9 @@ where async fn trace_raw_transaction( &self, data: &[u8], - trace_type: &[TraceType], + trace_types: &[TraceType], ) -> TransportResult { - self.client().request("trace_rawTransaction", (data, trace_type)).await + self.client().request("trace_rawTransaction", (data, trace_types)).await } async fn trace_filter( @@ -156,33 +153,31 @@ where self.client().request("trace_filter", (tracer,)).await } - async fn trace_block( - &self, - block: BlockNumberOrTag, - ) -> TransportResult> { + async fn trace_block(&self, block: BlockId) -> TransportResult> { self.client().request("trace_block", (block,)).await } async fn trace_replay_transaction( &self, hash: TxHash, - trace_type: &[TraceType], + trace_types: &[TraceType], ) -> TransportResult { - self.client().request("trace_replayTransaction", (hash, trace_type)).await + self.client().request("trace_replayTransaction", (hash, trace_types)).await } async fn trace_replay_block_transactions( &self, - block: BlockNumberOrTag, - trace_type: &[TraceType], + block: BlockId, + trace_types: &[TraceType], ) -> TransportResult> { - self.client().request("trace_replayBlockTransactions", (block, trace_type)).await + self.client().request("trace_replayBlockTransactions", (block, trace_types)).await } } #[cfg(test)] mod test { use crate::ProviderBuilder; + use alloy_eips::BlockNumberOrTag; use super::*; @@ -194,7 +189,7 @@ mod test { async fn test_trace_block() { init_tracing(); let provider = ProviderBuilder::new().on_anvil(); - let traces = provider.trace_block(BlockNumberOrTag::Latest).await.unwrap(); + let traces = provider.trace_block(BlockId::Number(BlockNumberOrTag::Latest)).await.unwrap(); assert_eq!(traces.len(), 0); } } diff --git a/crates/provider/src/provider/trait.rs b/crates/provider/src/provider/trait.rs index 4d2664718af..ec75c68b66b 100644 --- a/crates/provider/src/provider/trait.rs +++ b/crates/provider/src/provider/trait.rs @@ -259,10 +259,10 @@ pub trait Provider: /// Gets a block by either its hash, tag, or number, with full transactions or only hashes. async fn get_block( &self, - id: BlockId, + block: BlockId, kind: BlockTransactionsKind, ) -> TransportResult> { - match id { + match block { BlockId::Hash(hash) => self.get_block_by_hash(hash.into(), kind).await, BlockId::Number(number) => { let full = matches!(kind, BlockTransactionsKind::Full); @@ -320,10 +320,10 @@ pub trait Provider: Ok(block) } - /// Gets the selected block [BlockNumberOrTag] receipts. + /// Gets the selected block [BlockId] receipts. async fn get_block_receipts( &self, - block: BlockNumberOrTag, + block: BlockId, ) -> TransportResult>> { self.client().request("eth_getBlockReceipts", (block,)).await } @@ -1086,7 +1086,7 @@ mod tests { } } - #[cfg(feature = "ws")] + #[cfg(all(feature = "ws", not(windows)))] #[tokio::test] async fn subscribe_blocks_ws() { use futures::stream::StreamExt; @@ -1107,7 +1107,7 @@ mod tests { } } - #[cfg(feature = "ws")] + #[cfg(all(feature = "ws", not(windows)))] #[tokio::test] async fn subscribe_blocks_ws_boxed() { use futures::stream::StreamExt; @@ -1433,7 +1433,8 @@ mod tests { async fn gets_block_receipts() { init_tracing(); let provider = ProviderBuilder::new().on_anvil(); - let receipts = provider.get_block_receipts(BlockNumberOrTag::Latest).await.unwrap(); + let receipts = + provider.get_block_receipts(BlockId::Number(BlockNumberOrTag::Latest)).await.unwrap(); assert!(receipts.is_some()); } diff --git a/crates/provider/src/provider/with_block.rs b/crates/provider/src/provider/with_block.rs index 808b72a15f6..471e310c156 100644 --- a/crates/provider/src/provider/with_block.rs +++ b/crates/provider/src/provider/with_block.rs @@ -11,7 +11,7 @@ use std::{ task::Poll, }; -/// States of the +/// States of the [`RpcWithBlock`] future. #[derive(Clone)] enum States Output> where diff --git a/crates/rpc-client/src/builtin.rs b/crates/rpc-client/src/builtin.rs index ee0670ff849..6b95963a090 100644 --- a/crates/rpc-client/src/builtin.rs +++ b/crates/rpc-client/src/builtin.rs @@ -250,7 +250,7 @@ mod test { } #[test] - #[cfg(feature = "ipc")] + #[cfg(all(feature = "ipc", not(windows)))] fn test_parsing_ipc() { use alloy_node_bindings::Anvil; From c1d515156fa1736d76958b1ef77a678f7b0fd931 Mon Sep 17 00:00:00 2001 From: Oliver Date: Thu, 8 Aug 2024 14:20:59 +0200 Subject: [PATCH 068/186] chore(eip7702): devnet3 changes (#1056) * chore(eip7702): remove `OptionalNonce` * test: adjust auth list rpc tests * fix: add missing import * test: update eip7702 enc/dec fixture * chore: const fn * fix: serialize nonce w `alloy_serde::quantity` * chore: chain id is now u256 * feat: add new `PER_EMPTY_ACCOUNT_COST` constant * test: adjust tests --- crates/eips/src/eip7702/auth_list.rs | 112 +++----------------- crates/eips/src/eip7702/constants.rs | 7 ++ crates/rpc-types-eth/src/transaction/mod.rs | 12 +-- 3 files changed, 25 insertions(+), 106 deletions(-) diff --git a/crates/eips/src/eip7702/auth_list.rs b/crates/eips/src/eip7702/auth_list.rs index bfb0db9203c..52ec763c9a6 100644 --- a/crates/eips/src/eip7702/auth_list.rs +++ b/crates/eips/src/eip7702/auth_list.rs @@ -2,7 +2,7 @@ use core::ops::Deref; #[cfg(not(feature = "std"))] use alloc::vec::Vec; -use alloy_primitives::{keccak256, Address, ChainId, Signature, B256}; +use alloy_primitives::{keccak256, Address, Signature, B256, U256}; use alloy_rlp::{ length_of_length, BufMut, Decodable, Encodable, Header, Result as RlpResult, RlpDecodable, RlpEncodable, @@ -47,11 +47,12 @@ impl RecoveredAuthority { #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] pub struct Authorization { /// The chain ID of the authorization. - pub chain_id: ChainId, + pub chain_id: U256, /// The address of the authorization. pub address: Address, /// The nonce for the authorization. - pub nonce: OptionalNonce, + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))] + pub nonce: u64, } impl Authorization { @@ -60,7 +61,7 @@ impl Authorization { /// # Note /// /// Implementers should check that this matches the current `chain_id` *or* is 0. - pub const fn chain_id(&self) -> ChainId { + pub const fn chain_id(&self) -> U256 { self.chain_id } @@ -70,13 +71,8 @@ impl Authorization { } /// Get the `nonce` for the authorization. - /// - /// # Note - /// - /// If this is `Some`, implementers should check that the nonce of the authority is equal to - /// this nonce. - pub fn nonce(&self) -> Option { - *self.nonce + pub const fn nonce(&self) -> u64 { + self.nonce } /// Computes the signature hash used to sign the authorization, or recover the authority from a @@ -280,72 +276,6 @@ impl Deref for RecoveredAuthorization { } } -/// An internal wrapper around an `Option` for optional nonces. -/// -/// In EIP-7702 the nonce is encoded as a list of either 0 or 1 items, where 0 items means that no -/// nonce was specified (i.e. `None`). If there is 1 item, this is the same as `Some`. -/// -/// The wrapper type is used for RLP encoding and decoding. -#[derive(Default, Debug, Copy, Clone, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] -pub struct OptionalNonce(Option); - -impl OptionalNonce { - /// Create a new [`OptionalNonce`] - pub const fn new(nonce: Option) -> Self { - Self(nonce) - } -} - -impl From> for OptionalNonce { - fn from(value: Option) -> Self { - Self::new(value) - } -} - -impl Encodable for OptionalNonce { - fn encode(&self, out: &mut dyn BufMut) { - match self.0 { - Some(nonce) => { - Header { list: true, payload_length: nonce.length() }.encode(out); - nonce.encode(out); - } - None => Header { list: true, payload_length: 0 }.encode(out), - } - } - - fn length(&self) -> usize { - self.map(|nonce| nonce.length() + length_of_length(nonce.length())).unwrap_or(1) - } -} - -impl Decodable for OptionalNonce { - fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { - let mut bytes = Header::decode_bytes(buf, true)?; - if bytes.is_empty() { - return Ok(Self(None)); - } - - let payload_view = &mut bytes; - let nonce = u64::decode(payload_view)?; - if !payload_view.is_empty() { - // if there's more than 1 item in the nonce list we error - Err(alloy_rlp::Error::UnexpectedLength) - } else { - Ok(Self(Some(nonce))) - } - } -} - -impl Deref for OptionalNonce { - type Target = Option; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - #[cfg(test)] mod tests { use super::*; @@ -364,44 +294,26 @@ mod tests { fn test_encode_decode_auth() { // fully filled test_encode_decode_roundtrip(Authorization { - chain_id: 1u64, - address: Address::left_padding_from(&[6]), - nonce: Some(1u64).into(), - }); - - // no nonce - test_encode_decode_roundtrip(Authorization { - chain_id: 1u64, + chain_id: U256::from(1u64), address: Address::left_padding_from(&[6]), - nonce: None.into(), + nonce: 1, }); } - #[test] - fn opt_nonce_too_many_elements() { - let mut buf = Vec::new(); - vec![1u64, 2u64].encode(&mut buf); - - assert_eq!( - OptionalNonce::decode(&mut buf.as_ref()), - Err(alloy_rlp::Error::UnexpectedLength) - ) - } - #[test] fn test_encode_decode_signed_auth() { let auth = SignedAuthorization { inner: Authorization { - chain_id: 1u64, + chain_id: U256::from(1u64), address: Address::left_padding_from(&[6]), - nonce: Some(1u64).into(), + nonce: 1, }, signature: Signature::from_str("48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c8041b").unwrap(), }; let mut buf = Vec::new(); auth.encode(&mut buf); - let expected = "f85b01940000000000000000000000000000000000000006c1011ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804"; + let expected = "f85a01940000000000000000000000000000000000000006011ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804"; assert_eq!(hex::encode(&buf), expected); let decoded = SignedAuthorization::decode(&mut buf.as_ref()).unwrap(); diff --git a/crates/eips/src/eip7702/constants.rs b/crates/eips/src/eip7702/constants.rs index 18b0453f514..cc39b7f6a84 100644 --- a/crates/eips/src/eip7702/constants.rs +++ b/crates/eips/src/eip7702/constants.rs @@ -16,3 +16,10 @@ pub const MAGIC: u8 = 0x05; /// /// See also [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702). pub const PER_AUTH_BASE_COST: u64 = 2500; + +/// A gas refund for EIP7702 transactions if the authority account already exists in the trie. +/// +/// The refund is `PER_EMPTY_ACCOUNT_COST - PER_AUTH_BASE_COST`. +/// +/// See also [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702). +pub const PER_EMPTY_ACCOUNT_COST: u64 = 25000; diff --git a/crates/rpc-types-eth/src/transaction/mod.rs b/crates/rpc-types-eth/src/transaction/mod.rs index 809374ab6bb..ca93ba34dcb 100644 --- a/crates/rpc-types-eth/src/transaction/mod.rs +++ b/crates/rpc-types-eth/src/transaction/mod.rs @@ -347,9 +347,9 @@ mod tests { max_priority_fee_per_gas: Some(22), max_fee_per_blob_gas: None, authorization_list: Some(vec![(Authorization { - chain_id: 1u64, + chain_id: U256::from(1u64), address: Address::left_padding_from(&[6]), - nonce: Some(1u64).into(), + nonce: 1u64, }) .into_signed(AlloySignature::from_str("48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c8041b").unwrap())]), other: Default::default(), @@ -357,7 +357,7 @@ mod tests { let serialized = serde_json::to_string(&transaction).unwrap(); assert_eq!( serialized, - r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000001","nonce":"0x2","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000003","blockNumber":"0x4","transactionIndex":"0x5","from":"0x0000000000000000000000000000000000000006","to":"0x0000000000000000000000000000000000000007","value":"0x8","gasPrice":"0x9","gas":"0xa","maxFeePerGas":"0x15","maxPriorityFeePerGas":"0x16","input":"0x0b0c0d","r":"0xe","s":"0xe","v":"0xe","chainId":"0x11","type":"0x14","authorizationList":[{"chainId":1,"address":"0x0000000000000000000000000000000000000006","nonce":1,"r":"0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353","s":"0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","v":27}]}"# + r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000001","nonce":"0x2","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000003","blockNumber":"0x4","transactionIndex":"0x5","from":"0x0000000000000000000000000000000000000006","to":"0x0000000000000000000000000000000000000007","value":"0x8","gasPrice":"0x9","gas":"0xa","maxFeePerGas":"0x15","maxPriorityFeePerGas":"0x16","input":"0x0b0c0d","r":"0xe","s":"0xe","v":"0xe","chainId":"0x11","type":"0x14","authorizationList":[{"chainId":"0x1","address":"0x0000000000000000000000000000000000000006","nonce":"0x1","r":"0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353","s":"0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","v":27}]}"# ); let deserialized: Transaction = serde_json::from_str(&serialized).unwrap(); assert_eq!(transaction, deserialized); @@ -391,9 +391,9 @@ mod tests { max_priority_fee_per_gas: Some(22), max_fee_per_blob_gas: None, authorization_list: Some(vec![(Authorization { - chain_id: 1u64, + chain_id: U256::from(1u64), address: Address::left_padding_from(&[6]), - nonce: Some(1u64).into(), + nonce: 1u64, }) .into_signed(AlloySignature::from_str("48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c8041b").unwrap())]), other: Default::default(), @@ -401,7 +401,7 @@ mod tests { let serialized = serde_json::to_string(&transaction).unwrap(); assert_eq!( serialized, - r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000001","nonce":"0x2","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000003","blockNumber":"0x4","transactionIndex":"0x5","from":"0x0000000000000000000000000000000000000006","to":"0x0000000000000000000000000000000000000007","value":"0x8","gasPrice":"0x9","gas":"0xa","maxFeePerGas":"0x15","maxPriorityFeePerGas":"0x16","input":"0x0b0c0d","r":"0xe","s":"0xe","v":"0xe","yParity":"0x1","chainId":"0x11","type":"0x14","authorizationList":[{"chainId":1,"address":"0x0000000000000000000000000000000000000006","nonce":1,"r":"0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353","s":"0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","v":27}]}"# + r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000001","nonce":"0x2","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000003","blockNumber":"0x4","transactionIndex":"0x5","from":"0x0000000000000000000000000000000000000006","to":"0x0000000000000000000000000000000000000007","value":"0x8","gasPrice":"0x9","gas":"0xa","maxFeePerGas":"0x15","maxPriorityFeePerGas":"0x16","input":"0x0b0c0d","r":"0xe","s":"0xe","v":"0xe","yParity":"0x1","chainId":"0x11","type":"0x14","authorizationList":[{"chainId":"0x1","address":"0x0000000000000000000000000000000000000006","nonce":"0x1","r":"0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353","s":"0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","v":27}]}"# ); let deserialized: Transaction = serde_json::from_str(&serialized).unwrap(); assert_eq!(transaction, deserialized); From d000fc6b2a1f23af7a3c704c10cb89a4eb01fd01 Mon Sep 17 00:00:00 2001 From: morito Date: Fri, 9 Aug 2024 00:04:30 +0900 Subject: [PATCH 069/186] feat: Add 7702 tx enum (#1059) * feat: Add 7702 tx enum * fix import * rpc-types-eth: try_from method for 7702 tx * rpc-types-eth: skeleton impl for 7702 tx * skeleton impl for `build_7702` and `complete_7702` * network: Supprt 7702 tx * fix: format * Support 7702 tx in TransactionRequest * concensus/transaction: Add tests for 7702 tx * network: Add authorization_list accessor to TransactionBuilder * network: Add tests for 7702 tx * add missing authorization_list * fix: don't flatten auth list * chore: remove failed merge * test: adjust tests for non-opt nonce * fix: cover `TxType::Eip7702` * chore: missing import --------- Co-authored-by: Oliver Nordbjerg --- crates/consensus/src/lib.rs | 2 +- crates/consensus/src/receipt/envelope.rs | 23 +++- crates/consensus/src/transaction/envelope.rs | 103 ++++++++++++++++- crates/consensus/src/transaction/typed.rs | 28 ++++- crates/network/src/any/builder.rs | 9 ++ crates/network/src/ethereum/builder.rs | 55 ++++++++- crates/network/src/ethereum/wallet.rs | 4 + crates/network/src/transaction/builder.rs | 13 +++ crates/rpc-types-eth/src/transaction/error.rs | 3 + crates/rpc-types-eth/src/transaction/mod.rs | 36 +++++- .../rpc-types-eth/src/transaction/request.rs | 108 +++++++++++++++++- 11 files changed, 365 insertions(+), 19 deletions(-) diff --git a/crates/consensus/src/lib.rs b/crates/consensus/src/lib.rs index b1748bbde4c..5fd91a76559 100644 --- a/crates/consensus/src/lib.rs +++ b/crates/consensus/src/lib.rs @@ -34,7 +34,7 @@ pub mod transaction; pub use transaction::BlobTransactionValidationError; pub use transaction::{ SignableTransaction, Transaction, TxEip1559, TxEip2930, TxEip4844, TxEip4844Variant, - TxEip4844WithSidecar, TxEnvelope, TxLegacy, TxType, TypedTransaction, + TxEip4844WithSidecar, TxEip7702, TxEnvelope, TxLegacy, TxType, TypedTransaction, }; pub use alloy_eips::eip4844::{ diff --git a/crates/consensus/src/receipt/envelope.rs b/crates/consensus/src/receipt/envelope.rs index 66c51f436ef..476dba0d492 100644 --- a/crates/consensus/src/receipt/envelope.rs +++ b/crates/consensus/src/receipt/envelope.rs @@ -37,6 +37,11 @@ pub enum ReceiptEnvelope { /// [EIP-4844]: https://eips.ethereum.org/EIPS/eip-4844 #[cfg_attr(feature = "serde", serde(rename = "0x3", alias = "0x03"))] Eip4844(ReceiptWithBloom), + /// Receipt envelope with type flag 4, containing a [EIP-7702] receipt. + /// + /// [EIP-7702]: https://eips.ethereum.org/EIPS/eip-7702 + #[cfg_attr(feature = "serde", serde(rename = "0x4", alias = "0x04"))] + Eip7702(ReceiptWithBloom), } impl ReceiptEnvelope { @@ -48,6 +53,7 @@ impl ReceiptEnvelope { Self::Eip2930(_) => TxType::Eip2930, Self::Eip1559(_) => TxType::Eip1559, Self::Eip4844(_) => TxType::Eip4844, + Self::Eip7702(_) => TxType::Eip7702, } } @@ -80,7 +86,11 @@ impl ReceiptEnvelope { /// however, future receipt types may be added. pub const fn as_receipt_with_bloom(&self) -> Option<&ReceiptWithBloom> { match self { - Self::Legacy(t) | Self::Eip2930(t) | Self::Eip1559(t) | Self::Eip4844(t) => Some(t), + Self::Legacy(t) + | Self::Eip2930(t) + | Self::Eip1559(t) + | Self::Eip4844(t) + | Self::Eip7702(t) => Some(t), } } @@ -88,9 +98,11 @@ impl ReceiptEnvelope { /// receipt types may be added. pub const fn as_receipt(&self) -> Option<&Receipt> { match self { - Self::Legacy(t) | Self::Eip2930(t) | Self::Eip1559(t) | Self::Eip4844(t) => { - Some(&t.receipt) - } + Self::Legacy(t) + | Self::Eip2930(t) + | Self::Eip1559(t) + | Self::Eip4844(t) + | Self::Eip7702(t) => Some(&t.receipt), } } } @@ -168,6 +180,7 @@ impl Encodable2718 for ReceiptEnvelope { Self::Eip2930(_) => Some(TxType::Eip2930 as u8), Self::Eip1559(_) => Some(TxType::Eip1559 as u8), Self::Eip4844(_) => Some(TxType::Eip4844 as u8), + Self::Eip7702(_) => Some(TxType::Eip7702 as u8), } } @@ -191,6 +204,7 @@ impl Decodable2718 for ReceiptEnvelope { TxType::Eip2930 => Ok(Self::Eip2930(receipt)), TxType::Eip1559 => Ok(Self::Eip1559(receipt)), TxType::Eip4844 => Ok(Self::Eip4844(receipt)), + TxType::Eip7702 => Ok(Self::Eip7702(receipt)), TxType::Legacy => Err(Eip2718Error::UnexpectedType(0)), } } @@ -213,6 +227,7 @@ where 1 => Ok(Self::Eip2930(receipt)), 2 => Ok(Self::Eip1559(receipt)), 3 => Ok(Self::Eip4844(receipt)), + 4 => Ok(Self::Eip7702(receipt)), _ => unreachable!(), } } diff --git a/crates/consensus/src/transaction/envelope.rs b/crates/consensus/src/transaction/envelope.rs index a5e7e90c7f0..90ee3693838 100644 --- a/crates/consensus/src/transaction/envelope.rs +++ b/crates/consensus/src/transaction/envelope.rs @@ -1,6 +1,6 @@ use core::fmt; -use crate::{Signed, Transaction, TxEip1559, TxEip2930, TxLegacy}; +use crate::{Signed, Transaction, TxEip1559, TxEip2930, TxEip7702, TxLegacy}; use alloy_eips::eip2718::{Decodable2718, Eip2718Error, Eip2718Result, Encodable2718}; use alloy_primitives::{TxKind, B256}; use alloy_rlp::{Decodable, Encodable, Header}; @@ -26,6 +26,8 @@ pub enum TxType { Eip1559 = 2, /// EIP-4844 transaction type. Eip4844 = 3, + /// EIP-7702 transaction type. + Eip7702 = 4, } impl From for u8 { @@ -41,6 +43,7 @@ impl fmt::Display for TxType { Self::Eip2930 => write!(f, "EIP-2930"), Self::Eip1559 => write!(f, "EIP-1559"), Self::Eip4844 => write!(f, "EIP-4844"), + Self::Eip7702 => write!(f, "EIP-7702"), } } } @@ -61,6 +64,7 @@ impl TryFrom for TxType { 1 => Self::Eip2930, 2 => Self::Eip1559, 3 => Self::Eip4844, + 4 => Self::Eip7702, _ => return Err(Eip2718Error::UnexpectedType(value)), }) } @@ -101,6 +105,9 @@ pub enum TxEnvelope { /// send transactions to the network. #[cfg_attr(feature = "serde", serde(rename = "0x3", alias = "0x03"))] Eip4844(Signed), + /// A [`TxEip7702`] tagged with type 4. + #[cfg_attr(feature = "serde", serde(rename = "0x4", alias = "0x04"))] + Eip7702(Signed), } impl From> for TxEnvelope { @@ -141,6 +148,12 @@ impl From> for TxEnvelope { } } +impl From> for TxEnvelope { + fn from(v: Signed) -> Self { + Self::Eip7702(v) + } +} + impl TxEnvelope { /// Returns true if the transaction is a legacy transaction. #[inline] @@ -166,6 +179,12 @@ impl TxEnvelope { matches!(self, Self::Eip4844(_)) } + /// Returns true if the transaction is an EIP-7702 transaction. + #[inline] + pub const fn is_eip7702(&self) -> bool { + matches!(self, Self::Eip7702(_)) + } + /// Returns the [`TxLegacy`] variant if the transaction is a legacy transaction. pub const fn as_legacy(&self) -> Option<&Signed> { match self { @@ -198,6 +217,14 @@ impl TxEnvelope { } } + /// Returns the [`TxEip7702`] variant if the transaction is an EIP-7702 transaction. + pub const fn as_eip7702(&self) -> Option<&Signed> { + match self { + Self::Eip7702(tx) => Some(tx), + _ => None, + } + } + /// Recover the signer of the transaction. #[cfg(feature = "k256")] pub fn recover_signer( @@ -208,6 +235,7 @@ impl TxEnvelope { Self::Eip2930(tx) => tx.recover_signer(), Self::Eip1559(tx) => tx.recover_signer(), Self::Eip4844(tx) => tx.recover_signer(), + Self::Eip7702(tx) => tx.recover_signer(), } } @@ -218,6 +246,7 @@ impl TxEnvelope { Self::Eip2930(tx) => tx.signature_hash(), Self::Eip1559(tx) => tx.signature_hash(), Self::Eip4844(tx) => tx.signature_hash(), + Self::Eip7702(tx) => tx.signature_hash(), } } @@ -229,6 +258,7 @@ impl TxEnvelope { Self::Eip2930(tx) => tx.hash(), Self::Eip1559(tx) => tx.hash(), Self::Eip4844(tx) => tx.hash(), + Self::Eip7702(tx) => tx.hash(), } } @@ -240,6 +270,7 @@ impl TxEnvelope { Self::Eip2930(_) => TxType::Eip2930, Self::Eip1559(_) => TxType::Eip1559, Self::Eip4844(_) => TxType::Eip4844, + Self::Eip7702(_) => TxType::Eip7702, } } @@ -271,6 +302,10 @@ impl TxEnvelope { outer_header.length() + outer_payload_length } }, + Self::Eip7702(t) => { + let payload_length = t.tx().fields_len() + t.signature().rlp_vrs_len(); + Header { list: true, payload_length }.length() + payload_length + } } } @@ -321,6 +356,7 @@ impl Decodable2718 for TxEnvelope { TxType::Eip2930 => Ok(TxEip2930::decode_signed_fields(buf)?.into()), TxType::Eip1559 => Ok(TxEip1559::decode_signed_fields(buf)?.into()), TxType::Eip4844 => Ok(TxEip4844Variant::decode_signed_fields(buf)?.into()), + TxType::Eip7702 => Ok(TxEip7702::decode_signed_fields(buf)?.into()), TxType::Legacy => Err(Eip2718Error::UnexpectedType(0)), } } @@ -337,6 +373,7 @@ impl Encodable2718 for TxEnvelope { Self::Eip2930(_) => Some(TxType::Eip2930.into()), Self::Eip1559(_) => Some(TxType::Eip1559.into()), Self::Eip4844(_) => Some(TxType::Eip4844.into()), + Self::Eip7702(_) => Some(TxType::Eip7702.into()), } } @@ -357,6 +394,9 @@ impl Encodable2718 for TxEnvelope { Self::Eip4844(tx) => { tx.tx().encode_with_signature(tx.signature(), out, false); } + Self::Eip7702(tx) => { + tx.tx().encode_with_signature(tx.signature(), out, false); + } } } } @@ -368,6 +408,7 @@ impl Transaction for TxEnvelope { Self::Eip2930(tx) => tx.tx().chain_id(), Self::Eip1559(tx) => tx.tx().chain_id(), Self::Eip4844(tx) => tx.tx().chain_id(), + Self::Eip7702(tx) => tx.tx().chain_id(), } } @@ -377,6 +418,7 @@ impl Transaction for TxEnvelope { Self::Eip2930(tx) => tx.tx().gas_limit(), Self::Eip1559(tx) => tx.tx().gas_limit(), Self::Eip4844(tx) => tx.tx().gas_limit(), + Self::Eip7702(tx) => tx.tx().gas_limit(), } } @@ -386,6 +428,7 @@ impl Transaction for TxEnvelope { Self::Eip2930(tx) => tx.tx().gas_price(), Self::Eip1559(tx) => tx.tx().gas_price(), Self::Eip4844(tx) => tx.tx().gas_price(), + Self::Eip7702(tx) => tx.tx().gas_price(), } } @@ -395,6 +438,7 @@ impl Transaction for TxEnvelope { Self::Eip2930(tx) => tx.tx().input(), Self::Eip1559(tx) => tx.tx().input(), Self::Eip4844(tx) => tx.tx().input(), + Self::Eip7702(tx) => tx.tx().input(), } } @@ -404,6 +448,7 @@ impl Transaction for TxEnvelope { Self::Eip2930(tx) => tx.tx().nonce(), Self::Eip1559(tx) => tx.tx().nonce(), Self::Eip4844(tx) => tx.tx().nonce(), + Self::Eip7702(tx) => tx.tx().nonce(), } } @@ -413,6 +458,7 @@ impl Transaction for TxEnvelope { Self::Eip2930(tx) => tx.tx().to(), Self::Eip1559(tx) => tx.tx().to(), Self::Eip4844(tx) => tx.tx().to(), + Self::Eip7702(tx) => tx.tx().to(), } } @@ -422,6 +468,7 @@ impl Transaction for TxEnvelope { Self::Eip2930(tx) => tx.tx().value(), Self::Eip1559(tx) => tx.tx().value(), Self::Eip4844(tx) => tx.tx().value(), + Self::Eip7702(tx) => tx.tx().value(), } } } @@ -433,11 +480,12 @@ mod tests { use alloy_eips::{ eip2930::{AccessList, AccessListItem}, eip4844::BlobTransactionSidecar, + eip7702::Authorization, }; use alloy_primitives::{hex, Address, Parity, Signature, U256}; #[allow(unused_imports)] use alloy_primitives::{Bytes, TxKind}; - use std::{fs, path::PathBuf, vec}; + use std::{fs, path::PathBuf, str::FromStr, vec}; #[cfg(not(feature = "std"))] use std::vec::Vec; @@ -683,6 +731,31 @@ mod tests { test_encode_decode_roundtrip(tx, None); } + #[test] + fn test_encode_decode_eip7702() { + let tx = TxEip7702 { + chain_id: 1u64, + nonce: 2, + gas_limit: 3, + max_fee_per_gas: 4, + max_priority_fee_per_gas: 5, + to: Address::left_padding_from(&[5]).into(), + value: U256::from(6_u64), + input: vec![7].into(), + access_list: AccessList(vec![AccessListItem { + address: Address::left_padding_from(&[8]), + storage_keys: vec![B256::left_padding_from(&[9])], + }]), + authorization_list: vec![(Authorization { + chain_id: U256::from(1), + address: Address::left_padding_from(&[10]), + nonce: 1u64, + }) + .into_signed(Signature::from_str("48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c8041b").unwrap())], + }; + test_encode_decode_roundtrip(tx, None); + } + #[test] fn test_encode_decode_transaction_list() { let signature = Signature::test_signature(); @@ -827,4 +900,30 @@ mod tests { }); test_serde_roundtrip(tx); } + + #[test] + #[cfg(feature = "serde")] + fn test_serde_roundtrip_eip7702() { + let tx = TxEip7702 { + chain_id: u64::MAX, + nonce: u64::MAX, + gas_limit: u128::MAX, + max_fee_per_gas: u128::MAX, + max_priority_fee_per_gas: u128::MAX, + to: Address::random().into(), + value: U256::MAX, + input: Bytes::new(), + access_list: AccessList(vec![AccessListItem { + address: Address::random(), + storage_keys: vec![B256::random()], + }]), + authorization_list: vec![(Authorization { + chain_id: U256::from(1), + address: Address::left_padding_from(&[1]), + nonce: 1u64, + }) + .into_signed(Signature::from_str("48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c8041b").unwrap())], + }; + test_serde_roundtrip(tx); + } } diff --git a/crates/consensus/src/transaction/typed.rs b/crates/consensus/src/transaction/typed.rs index 38641ad4f9a..44062ea4a53 100644 --- a/crates/consensus/src/transaction/typed.rs +++ b/crates/consensus/src/transaction/typed.rs @@ -1,6 +1,6 @@ use crate::{ transaction::eip4844::{TxEip4844, TxEip4844Variant, TxEip4844WithSidecar}, - Transaction, TxEip1559, TxEip2930, TxEnvelope, TxLegacy, TxType, + Transaction, TxEip1559, TxEip2930, TxEip7702, TxEnvelope, TxLegacy, TxType, }; use alloy_primitives::{ChainId, TxKind}; @@ -28,6 +28,9 @@ pub enum TypedTransaction { /// EIP-4844 transaction #[cfg_attr(feature = "serde", serde(rename = "0x03", alias = "0x3"))] Eip4844(TxEip4844Variant), + /// EIP-7702 transaction + #[cfg_attr(feature = "serde", serde(rename = "0x04", alias = "0x4"))] + Eip7702(TxEip7702), } impl From for TypedTransaction { @@ -66,6 +69,12 @@ impl From for TypedTransaction { } } +impl From for TypedTransaction { + fn from(tx: TxEip7702) -> Self { + Self::Eip7702(tx) + } +} + impl From for TypedTransaction { fn from(envelope: TxEnvelope) -> Self { match envelope { @@ -73,6 +82,7 @@ impl From for TypedTransaction { TxEnvelope::Eip2930(tx) => Self::Eip2930(tx.strip_signature()), TxEnvelope::Eip1559(tx) => Self::Eip1559(tx.strip_signature()), TxEnvelope::Eip4844(tx) => Self::Eip4844(tx.strip_signature()), + TxEnvelope::Eip7702(tx) => Self::Eip7702(tx.strip_signature()), } } } @@ -86,6 +96,7 @@ impl TypedTransaction { Self::Eip2930(_) => TxType::Eip2930, Self::Eip1559(_) => TxType::Eip1559, Self::Eip4844(_) => TxType::Eip4844, + Self::Eip7702(_) => TxType::Eip7702, } } @@ -112,6 +123,14 @@ impl TypedTransaction { _ => None, } } + + /// Return the inner EIP-7702 transaction if it exists. + pub const fn eip7702(&self) -> Option<&TxEip7702> { + match self { + Self::Eip7702(tx) => Some(tx), + _ => None, + } + } } impl Transaction for TypedTransaction { @@ -121,6 +140,7 @@ impl Transaction for TypedTransaction { Self::Eip2930(tx) => tx.chain_id(), Self::Eip1559(tx) => tx.chain_id(), Self::Eip4844(tx) => tx.chain_id(), + Self::Eip7702(tx) => tx.chain_id(), } } @@ -130,6 +150,7 @@ impl Transaction for TypedTransaction { Self::Eip2930(tx) => tx.nonce(), Self::Eip1559(tx) => tx.nonce(), Self::Eip4844(tx) => tx.nonce(), + Self::Eip7702(tx) => tx.nonce(), } } @@ -139,6 +160,7 @@ impl Transaction for TypedTransaction { Self::Eip2930(tx) => tx.gas_limit(), Self::Eip1559(tx) => tx.gas_limit(), Self::Eip4844(tx) => tx.gas_limit(), + Self::Eip7702(tx) => tx.gas_limit(), } } @@ -148,6 +170,7 @@ impl Transaction for TypedTransaction { Self::Eip2930(tx) => tx.gas_price(), Self::Eip1559(tx) => tx.gas_price(), Self::Eip4844(tx) => tx.gas_price(), + Self::Eip7702(tx) => tx.gas_price(), } } @@ -157,6 +180,7 @@ impl Transaction for TypedTransaction { Self::Eip2930(tx) => tx.to(), Self::Eip1559(tx) => tx.to(), Self::Eip4844(tx) => tx.to(), + Self::Eip7702(tx) => tx.to(), } } @@ -166,6 +190,7 @@ impl Transaction for TypedTransaction { Self::Eip2930(tx) => tx.value(), Self::Eip1559(tx) => tx.value(), Self::Eip4844(tx) => tx.value(), + Self::Eip7702(tx) => tx.value(), } } @@ -175,6 +200,7 @@ impl Transaction for TypedTransaction { Self::Eip2930(tx) => tx.input(), Self::Eip1559(tx) => tx.input(), Self::Eip4844(tx) => tx.input(), + Self::Eip7702(tx) => tx.input(), } } } diff --git a/crates/network/src/any/builder.rs b/crates/network/src/any/builder.rs index 085fe750fd9..66618489e00 100644 --- a/crates/network/src/any/builder.rs +++ b/crates/network/src/any/builder.rs @@ -3,6 +3,7 @@ use crate::{ TransactionBuilderError, }; use alloy_consensus::BlobTransactionSidecar; +use alloy_eips::eip7702::SignedAuthorization; use alloy_primitives::{Address, Bytes, ChainId, TxKind, U256}; use alloy_rpc_types_eth::{AccessList, TransactionRequest}; use alloy_serde::WithOtherFields; @@ -119,6 +120,14 @@ impl TransactionBuilder for WithOtherFields { self.deref_mut().set_blob_sidecar(sidecar) } + fn authorization_list(&self) -> Option<&Vec> { + self.deref().authorization_list() + } + + fn set_authorization_list(&mut self, authorization_list: Vec) { + self.deref_mut().set_authorization_list(authorization_list) + } + fn complete_type(&self, ty: ::TxType) -> Result<(), Vec<&'static str>> { self.deref().complete_type(ty.try_into().map_err(|_| vec!["supported tx type"])?) } diff --git a/crates/network/src/ethereum/builder.rs b/crates/network/src/ethereum/builder.rs index 4a01db13997..6a807c67497 100644 --- a/crates/network/src/ethereum/builder.rs +++ b/crates/network/src/ethereum/builder.rs @@ -2,6 +2,7 @@ use crate::{ BuildResult, Ethereum, Network, NetworkWallet, TransactionBuilder, TransactionBuilderError, }; use alloy_consensus::{BlobTransactionSidecar, TxType, TypedTransaction}; +use alloy_eips::eip7702::SignedAuthorization; use alloy_primitives::{Address, Bytes, ChainId, TxKind, U256}; use alloy_rpc_types_eth::{request::TransactionRequest, AccessList}; @@ -115,12 +116,21 @@ impl TransactionBuilder for TransactionRequest { self.populate_blob_hashes(); } + fn authorization_list(&self) -> Option<&Vec> { + self.authorization_list.as_ref() + } + + fn set_authorization_list(&mut self, authorization_list: Vec) { + self.authorization_list = Some(authorization_list); + } + fn complete_type(&self, ty: TxType) -> Result<(), Vec<&'static str>> { match ty { TxType::Legacy => self.complete_legacy(), TxType::Eip2930 => self.complete_2930(), TxType::Eip1559 => self.complete_1559(), TxType::Eip4844 => self.complete_4844(), + TxType::Eip7702 => self.complete_7702(), } } @@ -183,8 +193,10 @@ impl TransactionBuilder for TransactionRequest { mod tests { use crate::{TransactionBuilder, TransactionBuilderError}; use alloy_consensus::{BlobTransactionSidecar, TxEip1559, TxType, TypedTransaction}; - use alloy_primitives::Address; + use alloy_eips::eip7702::Authorization; + use alloy_primitives::{Address, Signature, U256}; use alloy_rpc_types_eth::{AccessList, TransactionRequest}; + use std::str::FromStr; #[test] fn from_eip1559_to_tx_req() { @@ -237,6 +249,27 @@ mod tests { assert!(matches!(tx, TypedTransaction::Eip2930(_))); } + #[test] + fn test_7702_when_authorization_list() { + let request = TransactionRequest::default() + .with_nonce(1) + .with_gas_limit(0) + .with_max_fee_per_gas(0) + .with_max_priority_fee_per_gas(0) + .with_to(Address::ZERO) + .with_access_list(AccessList::default()) + .with_authorization_list(vec![(Authorization { + chain_id: U256::from(1), + address: Address::left_padding_from(&[1]), + nonce: 1u64, + }) + .into_signed(Signature::from_str("48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c8041b").unwrap())],); + + let tx = request.build_unsigned().unwrap(); + + assert!(matches!(tx, TypedTransaction::Eip7702(_))); + } + #[test] fn test_default_to_1559() { let request = TransactionRequest::default() @@ -346,4 +379,24 @@ mod tests { assert!(errors.contains(&"to")); assert!(errors.contains(&"max_fee_per_blob_gas")); } + + #[test] + fn test_invalid_7702_fields() { + let request = TransactionRequest::default().with_authorization_list(vec![]); + + let error = request.build_unsigned().unwrap_err(); + + let TransactionBuilderError::InvalidTransactionRequest(tx_type, errors) = error.error + else { + panic!("wrong variant") + }; + + assert_eq!(tx_type, TxType::Eip7702); + assert_eq!(errors.len(), 5); + assert!(errors.contains(&"to")); + assert!(errors.contains(&"nonce")); + assert!(errors.contains(&"gas_limit")); + assert!(errors.contains(&"max_priority_fee_per_gas")); + assert!(errors.contains(&"max_fee_per_gas")); + } } diff --git a/crates/network/src/ethereum/wallet.rs b/crates/network/src/ethereum/wallet.rs index 85df1e9e8b0..58e462d57eb 100644 --- a/crates/network/src/ethereum/wallet.rs +++ b/crates/network/src/ethereum/wallet.rs @@ -136,6 +136,10 @@ where let sig = self.sign_transaction_inner(sender, &mut t).await?; Ok(t.into_signed(sig).into()) } + TypedTransaction::Eip7702(mut t) => { + let sig = self.sign_transaction_inner(sender, &mut t).await?; + Ok(t.into_signed(sig).into()) + } } } } diff --git a/crates/network/src/transaction/builder.rs b/crates/network/src/transaction/builder.rs index 6ca5d6611e9..f2ba6bea84a 100644 --- a/crates/network/src/transaction/builder.rs +++ b/crates/network/src/transaction/builder.rs @@ -1,6 +1,7 @@ use super::signer::NetworkWallet; use crate::Network; use alloy_consensus::BlobTransactionSidecar; +use alloy_eips::eip7702::SignedAuthorization; use alloy_primitives::{Address, Bytes, ChainId, TxKind, U256}; use alloy_rpc_types_eth::AccessList; use alloy_sol_types::SolCall; @@ -299,6 +300,18 @@ pub trait TransactionBuilder: Default + Sized + Send + Sync + 'stati self } + /// Get the EIP-7702 authorization list for the transaction. + fn authorization_list(&self) -> Option<&Vec>; + + /// Sets the EIP-7702 authorization list. + fn set_authorization_list(&mut self, authorization_list: Vec); + + /// Builder-pattern method for setting the authorization list. + fn with_authorization_list(mut self, authorization_list: Vec) -> Self { + self.set_authorization_list(authorization_list); + self + } + /// Check if all necessary keys are present to build the specified type, /// returning a list of missing keys. fn complete_type(&self, ty: N::TxType) -> Result<(), Vec<&'static str>>; diff --git a/crates/rpc-types-eth/src/transaction/error.rs b/crates/rpc-types-eth/src/transaction/error.rs index b4f59ffbb1c..b285cbb48a4 100644 --- a/crates/rpc-types-eth/src/transaction/error.rs +++ b/crates/rpc-types-eth/src/transaction/error.rs @@ -43,6 +43,9 @@ pub enum ConversionError { /// Missing `blobVersionedHashes` field for EIP-4844 transaction. #[error("missing `blobVersionedHashes` field for EIP-4844 transaction")] MissingBlobVersionedHashes, + /// Missing `authorizationList` field for EIP-7702 transaction. + #[error("missing `authorizationList` field for EIP-7702 transaction")] + MissingAuthorizationList, /// Missing full transactions required for block decoding #[error("missing full transactions required for block decoding")] MissingFullTransactions, diff --git a/crates/rpc-types-eth/src/transaction/mod.rs b/crates/rpc-types-eth/src/transaction/mod.rs index ca93ba34dcb..1e29b7c9283 100644 --- a/crates/rpc-types-eth/src/transaction/mod.rs +++ b/crates/rpc-types-eth/src/transaction/mod.rs @@ -1,8 +1,8 @@ //! RPC types for transactions use alloy_consensus::{ - SignableTransaction, Signed, TxEip1559, TxEip2930, TxEip4844, TxEip4844Variant, TxEnvelope, - TxLegacy, TxType, + SignableTransaction, Signed, TxEip1559, TxEip2930, TxEip4844, TxEip4844Variant, TxEip7702, + TxEnvelope, TxLegacy, TxType, }; use alloy_eips::eip7702::SignedAuthorization; use alloy_network_primitives::TransactionResponse; @@ -98,8 +98,8 @@ pub struct Transaction { /// EIP2718 /// /// Transaction type, - /// Some(3) for EIP-4844 transaction, Some(2) for EIP-1559 transaction, - /// Some(1) for AccessList transaction, None or Some(0) for Legacy + /// Some(4) for EIP-7702 transaction, Some(3) for EIP-4844 transaction, Some(2) for EIP-1559 + /// transaction, Some(1) for AccessList transaction, None or Some(0) for Legacy #[serde( default, rename = "type", @@ -158,7 +158,7 @@ impl Transaction { max_fee_per_blob_gas: self.max_fee_per_blob_gas, blob_versioned_hashes: self.blob_versioned_hashes, sidecar: None, - authorization_list: None, + authorization_list: self.authorization_list, } } } @@ -265,6 +265,31 @@ impl TryFrom for Signed { } } +impl TryFrom for Signed { + type Error = ConversionError; + + fn try_from(tx: Transaction) -> Result { + let signature = tx.signature.ok_or(ConversionError::MissingSignature)?.try_into()?; + let tx = TxEip7702 { + chain_id: tx.chain_id.ok_or(ConversionError::MissingChainId)?, + nonce: tx.nonce, + gas_limit: tx.gas, + max_fee_per_gas: tx.max_fee_per_gas.ok_or(ConversionError::MissingMaxFeePerGas)?, + max_priority_fee_per_gas: tx + .max_priority_fee_per_gas + .ok_or(ConversionError::MissingMaxPriorityFeePerGas)?, + to: tx.to.into(), + value: tx.value, + access_list: tx.access_list.ok_or(ConversionError::MissingAccessList)?, + authorization_list: tx + .authorization_list + .ok_or(ConversionError::MissingAuthorizationList)?, + input: tx.input, + }; + Ok(tx.into_signed(signature)) + } +} + impl TryFrom for TxEnvelope { type Error = ConversionError; @@ -274,6 +299,7 @@ impl TryFrom for TxEnvelope { TxType::Eip1559 => Ok(Self::Eip1559(tx.try_into()?)), TxType::Eip2930 => Ok(Self::Eip2930(tx.try_into()?)), TxType::Eip4844 => Ok(Self::Eip4844(tx.try_into()?)), + TxType::Eip7702 => Ok(Self::Eip7702(tx.try_into()?)), } } } diff --git a/crates/rpc-types-eth/src/transaction/request.rs b/crates/rpc-types-eth/src/transaction/request.rs index 8061ab5b899..aacd3f3af70 100644 --- a/crates/rpc-types-eth/src/transaction/request.rs +++ b/crates/rpc-types-eth/src/transaction/request.rs @@ -2,8 +2,8 @@ use crate::{transaction::AccessList, BlobTransactionSidecar, Transaction}; use alloy_consensus::{ - TxEip1559, TxEip2930, TxEip4844, TxEip4844Variant, TxEip4844WithSidecar, TxEnvelope, TxLegacy, - TxType, TypedTransaction, + TxEip1559, TxEip2930, TxEip4844, TxEip4844Variant, TxEip4844WithSidecar, TxEip7702, TxEnvelope, + TxLegacy, TxType, TypedTransaction, }; use alloy_eips::eip7702::SignedAuthorization; use alloy_primitives::{Address, Bytes, ChainId, TxKind, B256, U256}; @@ -67,8 +67,8 @@ pub struct TransactionRequest { /// Blob sidecar for EIP-4844 transactions. #[serde(default, flatten, skip_serializing_if = "Option::is_none")] pub sidecar: Option, - /// Authorization list for for 7702 transactions. - #[serde(default, flatten, skip_serializing_if = "Option::is_none")] + /// Authorization list for for EIP-7702 transactions. + #[serde(default, skip_serializing_if = "Option::is_none")] pub authorization_list: Option>, } @@ -305,6 +305,33 @@ impl TransactionRequest { Ok(TxEip4844WithSidecar { sidecar, tx: self.build_4844_without_sidecar()? }) } + /// Build an EIP-7702 transaction. + /// + /// # Panics + /// + /// If required fields are missing. Use `complete_7702` to check if the + /// request can be built. + fn build_7702(self) -> Result { + let checked_to = self.to.ok_or("Missing 'to' field for Eip7702 transaction.")?; + + Ok(TxEip7702 { + chain_id: self.chain_id.unwrap_or(1), + nonce: self.nonce.ok_or("Missing 'nonce' field for Eip7702 transaction.")?, + gas_limit: self.gas.ok_or("Missing 'gas_limit' field for Eip7702 transaction.")?, + max_fee_per_gas: self + .max_fee_per_gas + .ok_or("Missing 'max_fee_per_gas' field for Eip7702 transaction.")?, + max_priority_fee_per_gas: self + .max_priority_fee_per_gas + .ok_or("Missing 'max_priority_fee_per_gas' field for Eip7702 transaction.")?, + to: checked_to, + value: self.value.unwrap_or_default(), + input: self.input.into_input().unwrap_or_default(), + access_list: self.access_list.unwrap_or_default(), + authorization_list: self.authorization_list.unwrap_or_default(), + }) + } + fn check_reqd_fields(&self) -> Vec<&'static str> { let mut missing = Vec::with_capacity(12); if self.nonce.is_none() { @@ -348,6 +375,7 @@ impl TransactionRequest { self.blob_versioned_hashes = None; self.sidecar = None; self.access_list = None; + self.authorization_list = None; } TxType::Eip2930 => { self.max_fee_per_gas = None; @@ -355,15 +383,24 @@ impl TransactionRequest { self.max_fee_per_blob_gas = None; self.blob_versioned_hashes = None; self.sidecar = None; + self.authorization_list = None; } TxType::Eip1559 => { self.gas_price = None; self.max_fee_per_blob_gas = None; self.blob_versioned_hashes = None; self.sidecar = None; + self.authorization_list = None; } TxType::Eip4844 => { self.gas_price = None; + self.authorization_list = None; + } + TxType::Eip7702 => { + self.gas_price = None; + self.max_fee_per_blob_gas = None; + self.blob_versioned_hashes = None; + self.sidecar = None; } } } @@ -371,12 +408,15 @@ impl TransactionRequest { /// Check this builder's preferred type, based on the fields that are set. /// /// Types are preferred as follows: + /// - EIP-7702 if authorization_list is set /// - EIP-4844 if sidecar or max_blob_fee_per_gas is set /// - EIP-2930 if access_list is set /// - Legacy if gas_price is set and access_list is unset /// - EIP-1559 in all other cases pub const fn preferred_type(&self) -> TxType { - if self.sidecar.is_some() || self.max_fee_per_blob_gas.is_some() { + if self.authorization_list.is_some() { + TxType::Eip7702 + } else if self.sidecar.is_some() || self.max_fee_per_blob_gas.is_some() { TxType::Eip4844 } else if self.access_list.is_some() && self.gas_price.is_some() { TxType::Eip2930 @@ -400,6 +440,7 @@ impl TransactionRequest { TxType::Eip2930 => self.complete_2930(), TxType::Eip1559 => self.complete_1559(), TxType::Eip4844 => self.complete_4844(), + TxType::Eip7702 => self.complete_7702(), } { Err((pref, missing)) } else { @@ -463,6 +504,23 @@ impl TransactionRequest { } } + /// Check if all necessary keys are present to build a 7702 transaction, + /// returning a list of keys that are missing. + pub fn complete_7702(&self) -> Result<(), Vec<&'static str>> { + let mut missing = self.check_reqd_fields(); + self.check_1559_fields(&mut missing); + + if self.authorization_list.is_none() { + missing.push("authorization_list"); + } + + if missing.is_empty() { + Ok(()) + } else { + Err(missing) + } + } + /// Check if all necessary keys are present to build a legacy transaction, /// returning a list of keys that are missing. pub fn complete_legacy(&self) -> Result<(), Vec<&'static str>> { @@ -485,6 +543,7 @@ impl TransactionRequest { TxType::Eip2930 => self.complete_2930().ok(), TxType::Eip1559 => self.complete_1559().ok(), TxType::Eip4844 => self.complete_4844().ok(), + TxType::Eip7702 => self.complete_7702().ok(), }?; Some(pref) } @@ -506,6 +565,7 @@ impl TransactionRequest { TxType::Eip1559 => self.build_1559().expect("checked)").into(), // `sidecar` is a hard requirement since this must be a _sendable_ transaction. TxType::Eip4844 => self.build_4844_with_sidecar().expect("checked)").into(), + TxType::Eip7702 => self.build_7702().expect("checked)").into(), }) } @@ -525,6 +585,7 @@ impl TransactionRequest { TxType::Eip2930 => self.clone().build_2930().map(Into::into), TxType::Eip1559 => self.clone().build_1559().map(Into::into), TxType::Eip4844 => self.clone().build_4844_variant().map(Into::into), + TxType::Eip7702 => self.clone().build_7702().map(Into::into), } .map_err(|msg| self.into_tx_err(msg)) } @@ -744,6 +805,25 @@ impl From for TransactionRequest { } } +impl From for TransactionRequest { + fn from(tx: TxEip7702) -> Self { + Self { + to: if let TxKind::Call(to) = tx.to { Some(to.into()) } else { None }, + gas: Some(tx.gas_limit), + max_fee_per_gas: Some(tx.max_fee_per_gas), + max_priority_fee_per_gas: Some(tx.max_priority_fee_per_gas), + value: Some(tx.value), + input: tx.input.into(), + nonce: Some(tx.nonce), + chain_id: Some(tx.chain_id), + access_list: Some(tx.access_list), + authorization_list: Some(tx.authorization_list), + transaction_type: Some(4), + ..Default::default() + } + } +} + impl From for TransactionRequest { fn from(tx: TypedTransaction) -> Self { match tx { @@ -751,6 +831,7 @@ impl From for TransactionRequest { TypedTransaction::Eip2930(tx) => tx.into(), TypedTransaction::Eip1559(tx) => tx.into(), TypedTransaction::Eip4844(tx) => tx.into(), + TypedTransaction::Eip7702(tx) => tx.into(), } } } @@ -826,6 +907,23 @@ impl From for TransactionRequest { tx.strip_signature().into() } } + TxEnvelope::Eip7702(tx) => { + #[cfg(feature = "k256")] + { + let from = tx.recover_signer().ok(); + let tx: Self = tx.strip_signature().into(); + if let Some(from) = from { + tx.from(from) + } else { + tx + } + } + + #[cfg(not(feature = "k256"))] + { + tx.strip_signature().into() + } + } _ => Default::default(), } } From fd159f6985058d2480fb89f63315e35680a07956 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Thu, 8 Aug 2024 18:44:31 +0200 Subject: [PATCH 070/186] chore: add missing 7702 check (#1137) fix: add missing 7702 check --- crates/network/src/ethereum/builder.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/network/src/ethereum/builder.rs b/crates/network/src/ethereum/builder.rs index 6a807c67497..e2328cca4c5 100644 --- a/crates/network/src/ethereum/builder.rs +++ b/crates/network/src/ethereum/builder.rs @@ -154,7 +154,9 @@ impl TransactionBuilder for TransactionRequest { let eip1559 = self.max_fee_per_gas.is_some() && self.max_priority_fee_per_gas.is_some(); let eip4844 = eip1559 && self.sidecar.is_some() && self.to.is_some(); - common && (legacy || eip2930 || eip1559 || eip4844) + + let eip7702 = eip1559 && self.authorization_list().is_some(); + common && (legacy || eip2930 || eip1559 || eip4844 || eip7702) } #[doc(alias = "output_transaction_type")] From 25f01704e81f94bae928bf4c91ba3cc7adf47100 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien?= <3535019+leruaa@users.noreply.github.com> Date: Thu, 8 Aug 2024 19:07:43 +0200 Subject: [PATCH 071/186] feat: make signature methods generic over EncodableSignature (#1138) --- crates/consensus/src/transaction/eip1559.rs | 12 +++++----- crates/consensus/src/transaction/eip2930.rs | 12 +++++----- crates/consensus/src/transaction/eip4844.rs | 25 ++++++++++----------- crates/consensus/src/transaction/eip7702.rs | 12 +++++----- 4 files changed, 27 insertions(+), 34 deletions(-) diff --git a/crates/consensus/src/transaction/eip1559.rs b/crates/consensus/src/transaction/eip1559.rs index 219cf98c6fd..9016095e4e2 100644 --- a/crates/consensus/src/transaction/eip1559.rs +++ b/crates/consensus/src/transaction/eip1559.rs @@ -105,7 +105,7 @@ impl TxEip1559 { /// - `value` /// - `data` (`input`) /// - `access_list` - pub(crate) fn decode_fields(buf: &mut &[u8]) -> alloy_rlp::Result { + pub fn decode_fields(buf: &mut &[u8]) -> alloy_rlp::Result { Ok(Self { chain_id: Decodable::decode(buf)?, nonce: Decodable::decode(buf)?, @@ -179,12 +179,10 @@ impl TxEip1559 { /// Inner encoding function that is used for both rlp [`Encodable`] trait and for calculating /// hash that for eip2718 does not require a rlp header. #[doc(hidden)] - pub fn encode_with_signature( - &self, - signature: &Signature, - out: &mut dyn BufMut, - with_header: bool, - ) { + pub fn encode_with_signature(&self, signature: &S, out: &mut dyn BufMut, with_header: bool) + where + S: EncodableSignature, + { let payload_length = self.fields_len() + signature.rlp_vrs_len(); if with_header { Header { diff --git a/crates/consensus/src/transaction/eip2930.rs b/crates/consensus/src/transaction/eip2930.rs index ee0f0896323..bffebce22f2 100644 --- a/crates/consensus/src/transaction/eip2930.rs +++ b/crates/consensus/src/transaction/eip2930.rs @@ -86,7 +86,7 @@ impl TxEip2930 { /// - `value` /// - `data` (`input`) /// - `access_list` - pub(crate) fn decode_fields(buf: &mut &[u8]) -> alloy_rlp::Result { + pub fn decode_fields(buf: &mut &[u8]) -> alloy_rlp::Result { Ok(Self { chain_id: Decodable::decode(buf)?, nonce: Decodable::decode(buf)?, @@ -157,12 +157,10 @@ impl TxEip2930 { /// Inner encoding function that is used for both rlp [`Encodable`] trait and for calculating /// hash that for eip2718 does not require a rlp header #[doc(hidden)] - pub fn encode_with_signature( - &self, - signature: &Signature, - out: &mut dyn BufMut, - with_header: bool, - ) { + pub fn encode_with_signature(&self, signature: &S, out: &mut dyn BufMut, with_header: bool) + where + S: EncodableSignature, + { let payload_length = self.fields_len() + signature.rlp_vrs_len(); if with_header { Header { diff --git a/crates/consensus/src/transaction/eip4844.rs b/crates/consensus/src/transaction/eip4844.rs index 0b886fcfe19..95f92c5a291 100644 --- a/crates/consensus/src/transaction/eip4844.rs +++ b/crates/consensus/src/transaction/eip4844.rs @@ -122,12 +122,10 @@ impl TxEip4844Variant { /// If `with_header` is `true`, the following will be encoded: /// `rlp(tx_type (0x03) || rlp([transaction_payload_body, blobs, commitments, proofs]))` #[doc(hidden)] - pub fn encode_with_signature( - &self, - signature: &Signature, - out: &mut dyn BufMut, - with_header: bool, - ) { + pub fn encode_with_signature(&self, signature: &S, out: &mut dyn BufMut, with_header: bool) + where + S: EncodableSignature, + { let payload_length = match self { Self::TxEip4844(tx) => tx.fields_len() + signature.rlp_vrs_len(), Self::TxEip4844WithSidecar(tx) => { @@ -519,12 +517,10 @@ impl TxEip4844 { /// Inner encoding function that is used for both rlp [`Encodable`] trait and for calculating /// hash that for eip2718 does not require a rlp header #[doc(hidden)] - pub fn encode_with_signature( - &self, - signature: &Signature, - out: &mut dyn BufMut, - with_header: bool, - ) { + pub fn encode_with_signature(&self, signature: &S, out: &mut dyn BufMut, with_header: bool) + where + S: EncodableSignature, + { let payload_length = self.fields_len() + signature.rlp_vrs_len(); if with_header { Header { @@ -778,7 +774,10 @@ impl TxEip4844WithSidecar { /// /// where `tx_payload` is the RLP encoding of the [TxEip4844] transaction fields: /// `rlp([chain_id, nonce, max_priority_fee_per_gas, ..., v, r, s])` - pub fn encode_with_signature_fields(&self, signature: &Signature, out: &mut dyn BufMut) { + pub fn encode_with_signature_fields(&self, signature: &S, out: &mut dyn BufMut) + where + S: EncodableSignature, + { let inner_payload_length = self.tx.fields_len() + signature.rlp_vrs_len(); let inner_header = Header { list: true, payload_length: inner_payload_length }; diff --git a/crates/consensus/src/transaction/eip7702.rs b/crates/consensus/src/transaction/eip7702.rs index 6db47db3905..2d5221ac2b0 100644 --- a/crates/consensus/src/transaction/eip7702.rs +++ b/crates/consensus/src/transaction/eip7702.rs @@ -110,7 +110,7 @@ impl TxEip7702 { /// - `data` (`input`) /// - `access_list` /// - `authorization_list` - pub(crate) fn decode_fields(buf: &mut &[u8]) -> alloy_rlp::Result { + pub fn decode_fields(buf: &mut &[u8]) -> alloy_rlp::Result { Ok(Self { chain_id: Decodable::decode(buf)?, nonce: Decodable::decode(buf)?, @@ -187,12 +187,10 @@ impl TxEip7702 { /// Inner encoding function that is used for both rlp [`Encodable`] trait and for calculating /// hash that for eip2718 does not require a rlp header. #[doc(hidden)] - pub fn encode_with_signature( - &self, - signature: &Signature, - out: &mut dyn BufMut, - with_header: bool, - ) { + pub fn encode_with_signature(&self, signature: &S, out: &mut dyn BufMut, with_header: bool) + where + S: EncodableSignature, + { let payload_length = self.fields_len() + signature.rlp_vrs_len(); if with_header { Header { From 56e317d9be3592363e5505dc7971053e15c45af1 Mon Sep 17 00:00:00 2001 From: Rohit Narurkar Date: Fri, 9 Aug 2024 19:13:38 +0100 Subject: [PATCH 072/186] fix(doc): correct order of fields (#1139) --- crates/eips/src/eip7702/auth_list.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/eips/src/eip7702/auth_list.rs b/crates/eips/src/eip7702/auth_list.rs index 52ec763c9a6..deb9e6c23f5 100644 --- a/crates/eips/src/eip7702/auth_list.rs +++ b/crates/eips/src/eip7702/auth_list.rs @@ -78,7 +78,7 @@ impl Authorization { /// Computes the signature hash used to sign the authorization, or recover the authority from a /// signed authorization list item. /// - /// The signature hash is `keccak(MAGIC || rlp([chain_id, [nonce], address]))` + /// The signature hash is `keccak(MAGIC || rlp([chain_id, address, nonce]))` #[inline] pub fn signature_hash(&self) -> B256 { use super::constants::MAGIC; From 9445ec6ca80ee9ecf918eec7d8bd3298f754d10d Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Mon, 12 Aug 2024 15:32:26 -0700 Subject: [PATCH 073/186] chore(deps): bump some deps --- Cargo.toml | 2 +- crates/provider/Cargo.toml | 2 +- crates/signer-gcp/Cargo.toml | 2 +- crates/signer-ledger/Cargo.toml | 2 +- crates/signer-local/Cargo.toml | 10 +++------- 5 files changed, 7 insertions(+), 11 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 301c474fd48..9067354f941 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -128,7 +128,7 @@ semver = "1.0" thiserror = "1.0" thiserror-no-std = "2.0.2" url = "2.5" -derive_more = "0.99.17" +derive_more = "1.0.0" ## serde serde = { version = "1.0", default-features = false, features = [ diff --git a/crates/provider/Cargo.toml b/crates/provider/Cargo.toml index d7b692c83e2..340441c8dad 100644 --- a/crates/provider/Cargo.toml +++ b/crates/provider/Cargo.toml @@ -45,7 +45,7 @@ alloy-chains.workspace = true async-stream = "0.3" async-trait.workspace = true auto_impl.workspace = true -dashmap = "5.5" +dashmap = "6.0" futures-utils-wasm.workspace = true futures.workspace = true lru = "0.12" diff --git a/crates/signer-gcp/Cargo.toml b/crates/signer-gcp/Cargo.toml index afa03fa123e..135048dc1b6 100644 --- a/crates/signer-gcp/Cargo.toml +++ b/crates/signer-gcp/Cargo.toml @@ -25,7 +25,7 @@ alloy-primitives.workspace = true alloy-signer.workspace = true async-trait.workspace = true -gcloud-sdk = { version = "0.24", features = [ +gcloud-sdk = { version = "0.25", features = [ "google-cloud-kms-v1", "google-longrunning", ] } diff --git a/crates/signer-ledger/Cargo.toml b/crates/signer-ledger/Cargo.toml index b3c6394b068..bd66e365bd5 100644 --- a/crates/signer-ledger/Cargo.toml +++ b/crates/signer-ledger/Cargo.toml @@ -24,7 +24,7 @@ alloy-primitives.workspace = true alloy-signer.workspace = true async-trait.workspace = true -coins-ledger = { version = "0.11", default-features = false } +coins-ledger = { version = "0.12", default-features = false } futures-util.workspace = true semver.workspace = true thiserror.workspace = true diff --git a/crates/signer-local/Cargo.toml b/crates/signer-local/Cargo.toml index d5980087b01..d4d3dc8cb82 100644 --- a/crates/signer-local/Cargo.toml +++ b/crates/signer-local/Cargo.toml @@ -34,17 +34,13 @@ elliptic-curve = { workspace = true, optional = true } eth-keystore = { version = "0.5.0", default-features = false, optional = true } # mnemonic -coins-bip32 = { version = "0.11.1", default-features = false, optional = true } -coins-bip39 = { version = "0.11.1", default-features = false, features = [ +coins-bip32 = { version = "0.12", default-features = false, optional = true } +coins-bip39 = { version = "0.12", default-features = false, features = [ "english", ], optional = true } # yubi -yubihsm = { version = "0.42", features = [ - "secp256k1", - "http", - "usb", -], optional = true } +yubihsm = { version = "0.42", features = ["secp256k1", "http", "usb"], optional = true } [dev-dependencies] alloy-dyn-abi.workspace = true From a2b3b2001546271557fd1590ae10cc06306a87e9 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Mon, 12 Aug 2024 15:38:17 -0700 Subject: [PATCH 074/186] Revert "chore(deps): bump some deps" This reverts commit 9445ec6ca80ee9ecf918eec7d8bd3298f754d10d. --- Cargo.toml | 2 +- crates/provider/Cargo.toml | 2 +- crates/signer-gcp/Cargo.toml | 2 +- crates/signer-ledger/Cargo.toml | 2 +- crates/signer-local/Cargo.toml | 10 +++++++--- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9067354f941..301c474fd48 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -128,7 +128,7 @@ semver = "1.0" thiserror = "1.0" thiserror-no-std = "2.0.2" url = "2.5" -derive_more = "1.0.0" +derive_more = "0.99.17" ## serde serde = { version = "1.0", default-features = false, features = [ diff --git a/crates/provider/Cargo.toml b/crates/provider/Cargo.toml index 340441c8dad..d7b692c83e2 100644 --- a/crates/provider/Cargo.toml +++ b/crates/provider/Cargo.toml @@ -45,7 +45,7 @@ alloy-chains.workspace = true async-stream = "0.3" async-trait.workspace = true auto_impl.workspace = true -dashmap = "6.0" +dashmap = "5.5" futures-utils-wasm.workspace = true futures.workspace = true lru = "0.12" diff --git a/crates/signer-gcp/Cargo.toml b/crates/signer-gcp/Cargo.toml index 135048dc1b6..afa03fa123e 100644 --- a/crates/signer-gcp/Cargo.toml +++ b/crates/signer-gcp/Cargo.toml @@ -25,7 +25,7 @@ alloy-primitives.workspace = true alloy-signer.workspace = true async-trait.workspace = true -gcloud-sdk = { version = "0.25", features = [ +gcloud-sdk = { version = "0.24", features = [ "google-cloud-kms-v1", "google-longrunning", ] } diff --git a/crates/signer-ledger/Cargo.toml b/crates/signer-ledger/Cargo.toml index bd66e365bd5..b3c6394b068 100644 --- a/crates/signer-ledger/Cargo.toml +++ b/crates/signer-ledger/Cargo.toml @@ -24,7 +24,7 @@ alloy-primitives.workspace = true alloy-signer.workspace = true async-trait.workspace = true -coins-ledger = { version = "0.12", default-features = false } +coins-ledger = { version = "0.11", default-features = false } futures-util.workspace = true semver.workspace = true thiserror.workspace = true diff --git a/crates/signer-local/Cargo.toml b/crates/signer-local/Cargo.toml index d4d3dc8cb82..d5980087b01 100644 --- a/crates/signer-local/Cargo.toml +++ b/crates/signer-local/Cargo.toml @@ -34,13 +34,17 @@ elliptic-curve = { workspace = true, optional = true } eth-keystore = { version = "0.5.0", default-features = false, optional = true } # mnemonic -coins-bip32 = { version = "0.12", default-features = false, optional = true } -coins-bip39 = { version = "0.12", default-features = false, features = [ +coins-bip32 = { version = "0.11.1", default-features = false, optional = true } +coins-bip39 = { version = "0.11.1", default-features = false, features = [ "english", ], optional = true } # yubi -yubihsm = { version = "0.42", features = ["secp256k1", "http", "usb"], optional = true } +yubihsm = { version = "0.42", features = [ + "secp256k1", + "http", + "usb", +], optional = true } [dev-dependencies] alloy-dyn-abi.workspace = true From d05326b6f3b549d6dc55a46ea5371cbb322f1b2b Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Mon, 12 Aug 2024 16:07:46 -0700 Subject: [PATCH 075/186] rpc-types-eth: rm `PeerCount` (#1140) * rpc-types-eth: add From u32 and U64 for PeerCount * rm PeerCount * fix clippy --- crates/rpc-types-eth/src/syncing.rs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/crates/rpc-types-eth/src/syncing.rs b/crates/rpc-types-eth/src/syncing.rs index 68bfd1d0f68..f2fda6fdf17 100644 --- a/crates/rpc-types-eth/src/syncing.rs +++ b/crates/rpc-types-eth/src/syncing.rs @@ -1,4 +1,4 @@ -use alloy_primitives::{B512, U256, U64}; +use alloy_primitives::{B512, U256}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; use std::collections::BTreeMap; @@ -47,16 +47,6 @@ pub struct Peers { pub peers: Vec, } -/// Number of peers connected to. -#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[serde(untagged)] -pub enum PeerCount { - /// Peer count as integer - Number(u32), - /// Peer count as hex - Hex(U64), -} - /// Peer connection information #[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] pub struct PeerInfo { From 5fe24e31e8194fcaaafeff3232ed30feb1360d46 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Tue, 13 Aug 2024 03:34:13 +0300 Subject: [PATCH 076/186] chore(deps): bump some deps (#1141) * chore(deps): bump some deps * feat: cla * feats --- Cargo.toml | 2 +- crates/eips/Cargo.toml | 30 +++++------------------------- crates/provider/Cargo.toml | 2 +- crates/signer-gcp/Cargo.toml | 2 +- crates/signer-ledger/Cargo.toml | 2 +- crates/signer-ledger/src/signer.rs | 3 +++ crates/signer-local/Cargo.toml | 10 +++------- 7 files changed, 15 insertions(+), 36 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 301c474fd48..9067354f941 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -128,7 +128,7 @@ semver = "1.0" thiserror = "1.0" thiserror-no-std = "2.0.2" url = "2.5" -derive_more = "0.99.17" +derive_more = "1.0.0" ## serde serde = { version = "1.0", default-features = false, features = [ diff --git a/crates/eips/Cargo.toml b/crates/eips/Cargo.toml index aaff60fa33d..f110ae2759d 100644 --- a/crates/eips/Cargo.toml +++ b/crates/eips/Cargo.toml @@ -28,7 +28,7 @@ serde = { workspace = true, optional = true } # kzg c-kzg = { workspace = true, optional = true } -derive_more = { workspace = true, optional = true } +derive_more = { workspace = true, features = ["as_ref", "deref", "deref_mut"], optional = true } once_cell = { workspace = true, features = ["race", "alloc"], optional = true } sha2 = { workspace = true, optional = true } @@ -44,39 +44,19 @@ k256 = { workspace = true, optional = true } rand = { workspace = true, optional = true } [dev-dependencies] -alloy-primitives = { workspace = true, features = [ - "rand", - "serde", - "arbitrary", -] } +alloy-primitives = { workspace = true, features = ["rand", "serde", "arbitrary"] } arbitrary = { workspace = true, features = ["derive"] } serde_json.workspace = true [features] default = ["std", "kzg-sidecar"] -std = [ - "alloy-primitives/std", - "alloy-rlp/std", - "serde?/std", - "c-kzg?/std", - "once_cell?/std", -] -serde = [ - "dep:alloy-serde", - "dep:serde", - "alloy-primitives/serde", - "c-kzg?/serde", -] +std = ["alloy-primitives/std", "alloy-rlp/std", "serde?/std", "c-kzg?/std", "once_cell?/std"] +serde = ["dep:alloy-serde", "dep:serde", "alloy-primitives/serde", "c-kzg?/serde"] kzg = ["kzg-sidecar", "sha2", "dep:derive_more", "dep:c-kzg", "dep:once_cell"] kzg-sidecar = ["sha2"] sha2 = ["dep:sha2"] k256 = ["alloy-primitives/k256", "dep:k256"] -ssz = [ - "std", - "dep:ethereum_ssz", - "dep:ethereum_ssz_derive", - "alloy-primitives/ssz", -] +ssz = ["std", "dep:ethereum_ssz", "dep:ethereum_ssz_derive", "alloy-primitives/ssz"] arbitrary = [ "std", "kzg-sidecar", diff --git a/crates/provider/Cargo.toml b/crates/provider/Cargo.toml index d7b692c83e2..340441c8dad 100644 --- a/crates/provider/Cargo.toml +++ b/crates/provider/Cargo.toml @@ -45,7 +45,7 @@ alloy-chains.workspace = true async-stream = "0.3" async-trait.workspace = true auto_impl.workspace = true -dashmap = "5.5" +dashmap = "6.0" futures-utils-wasm.workspace = true futures.workspace = true lru = "0.12" diff --git a/crates/signer-gcp/Cargo.toml b/crates/signer-gcp/Cargo.toml index afa03fa123e..135048dc1b6 100644 --- a/crates/signer-gcp/Cargo.toml +++ b/crates/signer-gcp/Cargo.toml @@ -25,7 +25,7 @@ alloy-primitives.workspace = true alloy-signer.workspace = true async-trait.workspace = true -gcloud-sdk = { version = "0.24", features = [ +gcloud-sdk = { version = "0.25", features = [ "google-cloud-kms-v1", "google-longrunning", ] } diff --git a/crates/signer-ledger/Cargo.toml b/crates/signer-ledger/Cargo.toml index b3c6394b068..bd66e365bd5 100644 --- a/crates/signer-ledger/Cargo.toml +++ b/crates/signer-ledger/Cargo.toml @@ -24,7 +24,7 @@ alloy-primitives.workspace = true alloy-signer.workspace = true async-trait.workspace = true -coins-ledger = { version = "0.11", default-features = false } +coins-ledger = { version = "0.12", default-features = false } futures-util.workspace = true semver.workspace = true thiserror.workspace = true diff --git a/crates/signer-ledger/src/signer.rs b/crates/signer-ledger/src/signer.rs index 360931e5725..32d32fb972f 100644 --- a/crates/signer-ledger/src/signer.rs +++ b/crates/signer-ledger/src/signer.rs @@ -149,6 +149,7 @@ impl LedgerSigner { let data = APDUData::new(&Self::path_to_bytes(derivation)); let command = APDUCommand { + cla: 0xe0, ins: INS::GET_PUBLIC_KEY as u8, p1: P1::NON_CONFIRM as u8, p2: P2::NO_CHAINCODE as u8, @@ -177,6 +178,7 @@ impl LedgerSigner { let transport = self.transport.lock().await; let command = APDUCommand { + cla: 0xe0, ins: INS::GET_APP_CONFIGURATION as u8, p1: P1::NON_CONFIRM as u8, p2: P2::NO_CHAINCODE as u8, @@ -235,6 +237,7 @@ impl LedgerSigner { async fn sign_payload(&self, command: INS, payload: &[u8]) -> Result { let transport = self.transport.lock().await; let mut command = APDUCommand { + cla: 0xe0, ins: command as u8, p1: P1_FIRST, p2: P2::NO_CHAINCODE as u8, diff --git a/crates/signer-local/Cargo.toml b/crates/signer-local/Cargo.toml index d5980087b01..d4d3dc8cb82 100644 --- a/crates/signer-local/Cargo.toml +++ b/crates/signer-local/Cargo.toml @@ -34,17 +34,13 @@ elliptic-curve = { workspace = true, optional = true } eth-keystore = { version = "0.5.0", default-features = false, optional = true } # mnemonic -coins-bip32 = { version = "0.11.1", default-features = false, optional = true } -coins-bip39 = { version = "0.11.1", default-features = false, features = [ +coins-bip32 = { version = "0.12", default-features = false, optional = true } +coins-bip39 = { version = "0.12", default-features = false, features = [ "english", ], optional = true } # yubi -yubihsm = { version = "0.42", features = [ - "secp256k1", - "http", - "usb", -], optional = true } +yubihsm = { version = "0.42", features = ["secp256k1", "http", "usb"], optional = true } [dev-dependencies] alloy-dyn-abi.workspace = true From dbe66836fee4906b0ece66f1ce768874e4d8dffc Mon Sep 17 00:00:00 2001 From: grandizzy <38490174+grandizzy@users.noreply.github.com> Date: Wed, 14 Aug 2024 10:01:25 -0700 Subject: [PATCH 077/186] Export types engine default features (#1143) Use types engine default feature --- crates/rpc-types/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/rpc-types/Cargo.toml b/crates/rpc-types/Cargo.toml index 48288e15ac1..a3163299856 100644 --- a/crates/rpc-types/Cargo.toml +++ b/crates/rpc-types/Cargo.toml @@ -34,7 +34,7 @@ serde = { workspace = true, features = ["derive", "std"]} serde_json.workspace = true [features] -default = ["eth"] +default = ["eth", "alloy-rpc-types-engine?/default"] admin = ["dep:alloy-rpc-types-admin"] anvil = ["dep:alloy-rpc-types-anvil"] beacon = ["dep:alloy-rpc-types-beacon"] From 98799ac203f1b6c1f1c1f8e152d26dd9e41b61eb Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Wed, 14 Aug 2024 20:20:14 +0300 Subject: [PATCH 078/186] chore: JSON-RPC 2.0 spelling (#1146) --- crates/json-rpc/Cargo.toml | 2 +- crates/json-rpc/README.md | 6 +++--- crates/json-rpc/src/response/error.rs | 4 ++-- crates/json-rpc/src/response/mod.rs | 4 ++-- crates/json-rpc/src/response/payload.rs | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/crates/json-rpc/Cargo.toml b/crates/json-rpc/Cargo.toml index 81a2d6b9b28..79558bd1651 100644 --- a/crates/json-rpc/Cargo.toml +++ b/crates/json-rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "alloy-json-rpc" -description = "Core types for JSON-RPC2.0 clients" +description = "Core types for JSON-RPC 2.0 clients" version.workspace = true edition.workspace = true diff --git a/crates/json-rpc/README.md b/crates/json-rpc/README.md index ac69e913bf6..6bc7f3f54f5 100644 --- a/crates/json-rpc/README.md +++ b/crates/json-rpc/README.md @@ -1,15 +1,15 @@ # alloy-json-rpc -Core types for JSON-RPC2.0 clients. +Core types for JSON-RPC 2.0 clients. -This crate includes data types and traits for JSON-RPC2.0 requests and +This crate includes data types and traits for JSON-RPC 2.0 requests and responses, targeted at RPC client usage. ### Core Model -A JSON-RPC2.0 request is a JSON object containing an ID, a method name, and +A JSON-RPC 2.0 request is a JSON object containing an ID, a method name, and an arbitrary parameters object. The parameters object may be omitted if empty. Any object that may be Serialized and Cloned may be used as RPC Parameters. diff --git a/crates/json-rpc/src/response/error.rs b/crates/json-rpc/src/response/error.rs index 0d318837059..ef8ac856b9c 100644 --- a/crates/json-rpc/src/response/error.rs +++ b/crates/json-rpc/src/response/error.rs @@ -7,7 +7,7 @@ use serde::{ use serde_json::{value::RawValue, Value}; use std::{borrow::Borrow, fmt, marker::PhantomData}; -/// A JSONRPC-2.0 error object. +/// A JSON-RPC 2.0 error object. /// /// This response indicates that the server received and handled the request, /// but that there was an error in the processing of it. The error should be @@ -165,7 +165,7 @@ impl<'de, ErrData: Deserialize<'de>> Deserialize<'de> for ErrorPayload type Value = ErrorPayload; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(formatter, "a JSON-RPC2.0 error object") + write!(formatter, "a JSON-RPC 2.0 error object") } fn visit_map(self, mut map: A) -> Result diff --git a/crates/json-rpc/src/response/mod.rs b/crates/json-rpc/src/response/mod.rs index f26e18f7413..6dfd1e32d29 100644 --- a/crates/json-rpc/src/response/mod.rs +++ b/crates/json-rpc/src/response/mod.rs @@ -13,9 +13,9 @@ pub use error::{BorrowedErrorPayload, ErrorPayload}; mod payload; pub use payload::{BorrowedResponsePayload, ResponsePayload}; -/// A JSONRPC-2.0 response object containing a [`ResponsePayload`]. +/// A JSON-RPC 2.0 response object containing a [`ResponsePayload`]. /// -/// This object is used to represent a JSONRPC-2.0 response. It may contain +/// This object is used to represent a JSON-RPC 2.0 response. It may contain /// either a successful result or an error. The `id` field is used to match /// the response to the request that it is responding to, and should be /// mirrored from the response. diff --git a/crates/json-rpc/src/response/payload.rs b/crates/json-rpc/src/response/payload.rs index 92b1dc6bd15..5c541ad3474 100644 --- a/crates/json-rpc/src/response/payload.rs +++ b/crates/json-rpc/src/response/payload.rs @@ -3,9 +3,9 @@ use serde::{de::DeserializeOwned, Deserialize}; use serde_json::value::RawValue; use std::borrow::Borrow; -/// A JSONRPC-2.0 response payload. +/// A JSON-RPC 2.0 response payload. /// -/// This enum covers both the success and error cases of a JSONRPC-2.0 +/// This enum covers both the success and error cases of a JSON-RPC 2.0 /// response. It is used to represent the `result` and `error` fields of a /// response object. /// From 511ae9820210798d4a35f1e28a7993bb5d445cd4 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Thu, 15 Aug 2024 01:33:31 +0800 Subject: [PATCH 079/186] fix: return more user-friendly error on tx timeout (#1145) * fix: return more user-friendly error on tx timeout * fix contract * fix ci * fix doc --- crates/contract/src/error.rs | 4 ++ crates/provider/Cargo.toml | 1 + crates/provider/src/heart.rs | 66 +++++++++++++++++++-------- crates/provider/src/lib.rs | 5 +- crates/provider/src/provider/trait.rs | 32 +++++++------ 5 files changed, 76 insertions(+), 32 deletions(-) diff --git a/crates/contract/src/error.rs b/crates/contract/src/error.rs index 0c382e0e00f..4b9ebe48762 100644 --- a/crates/contract/src/error.rs +++ b/crates/contract/src/error.rs @@ -1,5 +1,6 @@ use alloy_dyn_abi::Error as AbiError; use alloy_primitives::Selector; +use alloy_provider::PendingTransactionError; use alloy_transport::TransportError; use thiserror::Error; @@ -27,6 +28,9 @@ pub enum Error { /// An error occurred interacting with a contract over RPC. #[error(transparent)] TransportError(#[from] TransportError), + /// An error occured while waiting for a pending transaction. + #[error(transparent)] + PendingTransactionError(#[from] PendingTransactionError), } impl From for Error { diff --git a/crates/provider/Cargo.toml b/crates/provider/Cargo.toml index 340441c8dad..c671cd2f263 100644 --- a/crates/provider/Cargo.toml +++ b/crates/provider/Cargo.toml @@ -53,6 +53,7 @@ pin-project.workspace = true reqwest = { workspace = true, optional = true } serde_json.workspace = true serde.workspace = true +thiserror.workspace = true tokio = { workspace = true, features = ["sync", "macros"] } tracing.workspace = true url = { workspace = true, optional = true } diff --git a/crates/provider/src/heart.rs b/crates/provider/src/heart.rs index 58de345c6a2..d7f044530fb 100644 --- a/crates/provider/src/heart.rs +++ b/crates/provider/src/heart.rs @@ -5,7 +5,7 @@ use alloy_json_rpc::RpcError; use alloy_network::Network; use alloy_primitives::{TxHash, B256}; use alloy_rpc_types_eth::Block; -use alloy_transport::{utils::Spawnable, Transport, TransportErrorKind, TransportResult}; +use alloy_transport::{utils::Spawnable, Transport, TransportError}; use futures::{stream::StreamExt, FutureExt, Stream}; use std::{ collections::{BTreeMap, HashMap, HashSet, VecDeque}, @@ -18,6 +18,26 @@ use tokio::{ sync::{mpsc, oneshot, watch}, }; +/// Errors which may occur when watching a pending transaction. +#[derive(Debug, thiserror::Error)] +pub enum PendingTransactionError { + /// Failed to register pending transaction in heartbeat. + #[error("failed to register pending transaction to watch")] + FailedToRegister, + + /// Underlying transport error. + #[error(transparent)] + TransportError(#[from] TransportError), + + /// Error occured while getting response from the heartbeat. + #[error(transparent)] + Recv(#[from] oneshot::error::RecvError), + + /// Errors that may occur when watching a transaction. + #[error(transparent)] + TxWatcher(#[from] WatchTxError), +} + /// A builder for configuring a pending transaction watcher. /// /// # Examples @@ -157,7 +177,7 @@ impl<'a, T: Transport + Clone, N: Network> PendingTransactionBuilder<'a, T, N> { /// - [`get_receipt`](Self::get_receipt) for fetching the receipt after the transaction has been /// confirmed. #[doc(alias = "build")] - pub async fn register(self) -> TransportResult { + pub async fn register(self) -> Result { self.provider.watch_pending_transaction(self.config).await } @@ -168,7 +188,7 @@ impl<'a, T: Transport + Clone, N: Network> PendingTransactionBuilder<'a, T, N> { /// confirmed. /// - [`get_receipt`](Self::get_receipt) for fetching the receipt after the transaction has been /// confirmed. - pub async fn watch(self) -> TransportResult { + pub async fn watch(self) -> Result { self.register().await?.await } @@ -183,7 +203,7 @@ impl<'a, T: Transport + Clone, N: Network> PendingTransactionBuilder<'a, T, N> { /// - [`register`](Self::register): for registering the transaction without waiting for it to be /// confirmed. /// - [`watch`](Self::watch) for watching the transaction without fetching the receipt. - pub async fn get_receipt(self) -> TransportResult { + pub async fn get_receipt(self) -> Result { let hash = self.config.tx_hash; let mut pending_tx = self.provider.watch_pending_transaction(self.config).await?; @@ -209,7 +229,7 @@ impl<'a, T: Transport + Clone, N: Network> PendingTransactionBuilder<'a, T, N> { } if confirmed { - return Err(RpcError::NullResp); + return Err(RpcError::NullResp.into()); } } } @@ -303,20 +323,28 @@ impl PendingTransactionConfig { } } +/// Errors which may occur in heartbeat when watching a transaction. +#[derive(Debug, thiserror::Error)] +pub enum WatchTxError { + /// Transaction was not confirmed after configured timeout. + #[error("transaction was not confirmed within the timeout")] + Timeout, +} + #[doc(alias = "TransactionWatcher")] struct TxWatcher { config: PendingTransactionConfig, /// The block at which the transaction was received. To be filled once known. /// Invariant: any confirmed transaction in `Heart` has this value set. received_at_block: Option, - tx: oneshot::Sender<()>, + tx: oneshot::Sender>, } impl TxWatcher { /// Notify the waiter. - fn notify(self) { + fn notify(self, result: Result<(), WatchTxError>) { debug!(tx=%self.config.tx_hash, "notifying"); - let _ = self.tx.send(()); + let _ = self.tx.send(result); } } @@ -332,7 +360,7 @@ pub struct PendingTransaction { pub(crate) tx_hash: TxHash, /// The receiver for the notification. // TODO: send a receipt? - pub(crate) rx: oneshot::Receiver<()>, + pub(crate) rx: oneshot::Receiver>, } impl fmt::Debug for PendingTransaction { @@ -345,7 +373,7 @@ impl PendingTransaction { /// Creates a ready pending transaction. pub fn ready(tx_hash: TxHash) -> Self { let (tx, rx) = oneshot::channel(); - tx.send(()).ok(); // Make sure that the receiver is notified already. + tx.send(Ok(())).ok(); // Make sure that the receiver is notified already. Self { tx_hash, rx } } @@ -357,15 +385,16 @@ impl PendingTransaction { } impl Future for PendingTransaction { - type Output = TransportResult; + type Output = Result; fn poll( mut self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<'_>, ) -> std::task::Poll { - self.rx - .poll_unpin(cx) - .map(|res| res.map(|()| self.tx_hash).map_err(|_| TransportErrorKind::backend_gone())) + self.rx.poll_unpin(cx).map(|res| { + res??; + Ok(self.tx_hash) + }) } } @@ -437,7 +466,7 @@ impl Heartbeat { let to_keep = self.waiting_confs.split_off(&(current_height + 1)); let to_notify = std::mem::replace(&mut self.waiting_confs, to_keep); for watcher in to_notify.into_values().flatten() { - watcher.notify(); + watcher.notify(Ok(())); } } @@ -457,8 +486,9 @@ impl Heartbeat { let to_reap = std::mem::replace(&mut self.reap_at, to_keep); for tx_hash in to_reap.values() { - if self.unconfirmed.remove(tx_hash).is_some() { + if let Some(watcher) = self.unconfirmed.remove(tx_hash) { debug!(tx=%tx_hash, "reaped"); + watcher.notify(Err(WatchTxError::Timeout)); } } } @@ -510,7 +540,7 @@ impl Heartbeat { let current_height = self.past_blocks.back().map(|(h, _)| *h).unwrap(); if confirmed_at <= current_height { - to_watch.notify(); + to_watch.notify(Ok(())); } else { debug!(tx=%to_watch.config.tx_hash, %block_height, confirmations, "adding to waiting list"); self.waiting_confs.entry(confirmed_at).or_default().push(to_watch); @@ -567,7 +597,7 @@ impl Heartbeat { // If `confirmations` is not more than 1 we can notify the watcher immediately. let confirmations = watcher.config.required_confirmations; if confirmations <= 1 { - watcher.notify(); + watcher.notify(Ok(())); continue; } // Otherwise add it to the waiting list. diff --git a/crates/provider/src/lib.rs b/crates/provider/src/lib.rs index 314e1ff2494..416c98da727 100644 --- a/crates/provider/src/lib.rs +++ b/crates/provider/src/lib.rs @@ -36,7 +36,10 @@ pub mod layers; mod chain; mod heart; -pub use heart::{PendingTransaction, PendingTransactionBuilder, PendingTransactionConfig}; +pub use heart::{ + PendingTransaction, PendingTransactionBuilder, PendingTransactionConfig, + PendingTransactionError, WatchTxError, +}; mod provider; pub use provider::{ diff --git a/crates/provider/src/provider/trait.rs b/crates/provider/src/provider/trait.rs index ec75c68b66b..3515440e5df 100644 --- a/crates/provider/src/provider/trait.rs +++ b/crates/provider/src/provider/trait.rs @@ -1,6 +1,7 @@ //! Ethereum JSON-RPC provider. use crate::{ + heart::PendingTransactionError, utils::{self, Eip1559Estimation, EstimatorFunction}, EthCall, Identity, PendingTransaction, PendingTransactionBuilder, PendingTransactionConfig, ProviderBuilder, RootProvider, RpcWithBlock, SendableTx, @@ -18,7 +19,7 @@ use alloy_rpc_types_eth::{ AccessListResult, Block, BlockId, BlockNumberOrTag, EIP1186AccountProofResponse, FeeHistory, Filter, FilterChanges, Log, SyncStatus, }; -use alloy_transport::{BoxTransport, Transport, TransportErrorKind, TransportResult}; +use alloy_transport::{BoxTransport, Transport, TransportResult}; use serde_json::value::RawValue; use std::borrow::Cow; @@ -481,7 +482,7 @@ pub trait Provider: async fn watch_pending_transaction( &self, config: PendingTransactionConfig, - ) -> TransportResult { + ) -> Result { self.root().watch_pending_transaction(config).await } @@ -691,8 +692,8 @@ pub trait Provider: /// # Errors /// /// This method is only available on `pubsub` clients, such as WebSockets or IPC, and will - /// return a [`PubsubUnavailable`](TransportErrorKind::PubsubUnavailable) transport error if the - /// client does not support it. + /// return a [`PubsubUnavailable`](alloy_transport::TransportErrorKind::PubsubUnavailable) + /// transport error if the client does not support it. /// /// For a polling alternative available over HTTP, use [`Provider::watch_blocks`]. /// However, be aware that polling increases RPC usage drastically. @@ -723,8 +724,8 @@ pub trait Provider: /// # Errors /// /// This method is only available on `pubsub` clients, such as WebSockets or IPC, and will - /// return a [`PubsubUnavailable`](TransportErrorKind::PubsubUnavailable) transport error if the - /// client does not support it. + /// return a [`PubsubUnavailable`](alloy_transport::TransportErrorKind::PubsubUnavailable) + /// transport error if the client does not support it. /// /// For a polling alternative available over HTTP, use [`Provider::watch_pending_transactions`]. /// However, be aware that polling increases RPC usage drastically. @@ -761,8 +762,8 @@ pub trait Provider: /// # Errors /// /// This method is only available on `pubsub` clients, such as WebSockets or IPC, and will - /// return a [`PubsubUnavailable`](TransportErrorKind::PubsubUnavailable) transport error if the - /// client does not support it. + /// return a [`PubsubUnavailable`](alloy_transport::TransportErrorKind::PubsubUnavailable) + /// transport error if the client does not support it. /// /// For a polling alternative available over HTTP, use /// [`Provider::watch_full_pending_transactions`]. However, be aware that polling increases @@ -796,8 +797,8 @@ pub trait Provider: /// # Errors /// /// This method is only available on `pubsub` clients, such as WebSockets or IPC, and will - /// return a [`PubsubUnavailable`](TransportErrorKind::PubsubUnavailable) transport error if the - /// client does not support it. + /// return a [`PubsubUnavailable`](alloy_transport::TransportErrorKind::PubsubUnavailable) + /// transport error if the client does not support it. /// /// For a polling alternative available over HTTP, use /// [`Provider::watch_logs`]. However, be aware that polling increases @@ -894,6 +895,8 @@ pub trait Provider: /// # Ok(()) /// # } /// ``` + /// + /// [`PubsubUnavailable`]: alloy_transport::TransportErrorKind::PubsubUnavailable async fn raw_request(&self, method: Cow<'static, str>, params: P) -> TransportResult where P: RpcParam, @@ -962,7 +965,7 @@ impl Provider for RootProvider { async fn watch_pending_transaction( &self, config: PendingTransactionConfig, - ) -> TransportResult { + ) -> Result { let block_number = if let Some(receipt) = self.get_transaction_receipt(*config.tx_hash()).await? { // The transaction is already confirmed. @@ -979,7 +982,7 @@ impl Provider for RootProvider { self.get_heart() .watch_tx(config, block_number) .await - .map_err(|_| TransportErrorKind::backend_gone()) + .map_err(|_| PendingTransactionError::FailedToRegister) } } @@ -1069,7 +1072,10 @@ mod tests { let provider = ProviderBuilder::new().on_anvil_with_config(|a| a.block_time(1)); let err = provider.subscribe_blocks().await.unwrap_err(); - let alloy_json_rpc::RpcError::Transport(TransportErrorKind::PubsubUnavailable) = err else { + let alloy_json_rpc::RpcError::Transport( + alloy_transport::TransportErrorKind::PubsubUnavailable, + ) = err + else { panic!("{err:?}"); }; } From f5eaddf7a561cdf3ae06f3ff299ba4077da8999d Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Thu, 15 Aug 2024 15:23:20 -0700 Subject: [PATCH 080/186] fix(rpc-types-eth): match 7702 in TxReceipt.status() (#1149) fix(rpc-type-eth): match 7702 in TxReceipt.status() --- crates/rpc-types-eth/src/transaction/receipt.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/rpc-types-eth/src/transaction/receipt.rs b/crates/rpc-types-eth/src/transaction/receipt.rs index a95e5dce66b..f9336f09c5c 100644 --- a/crates/rpc-types-eth/src/transaction/receipt.rs +++ b/crates/rpc-types-eth/src/transaction/receipt.rs @@ -77,6 +77,7 @@ impl TransactionReceipt { ReceiptEnvelope::Eip1559(receipt) | ReceiptEnvelope::Eip2930(receipt) | ReceiptEnvelope::Eip4844(receipt) + | ReceiptEnvelope::Eip7702(receipt) | ReceiptEnvelope::Legacy(receipt) => receipt.receipt.status.coerce_status(), _ => false, } From 502d69b799223a44ff66c849f5336a3112f1cedd Mon Sep 17 00:00:00 2001 From: Delweng Date: Sun, 18 Aug 2024 00:56:28 +0800 Subject: [PATCH 081/186] feat(geth/trace): add field log.position (#1150) * chore(geth): add position in CallLogFrame Signed-off-by: jsvisa * typo: json indent Signed-off-by: jsvisa * test: add position in with_log Signed-off-by: jsvisa * chore(call): position use u64 instead Signed-off-by: jsvisa * use Option Signed-off-by: jsvisa * fix: skip serialize if none Signed-off-by: jsvisa --------- Signed-off-by: jsvisa --- crates/rpc-types-trace/src/geth/call.rs | 5 ++++- .../rpc-types-trace/test_data/call_tracer/with_log.json | 9 +++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/crates/rpc-types-trace/src/geth/call.rs b/crates/rpc-types-trace/src/geth/call.rs index 76092be2a79..5555b9acba5 100644 --- a/crates/rpc-types-trace/src/geth/call.rs +++ b/crates/rpc-types-trace/src/geth/call.rs @@ -44,7 +44,7 @@ pub struct CallFrame { pub typ: String, } -/// Represents a recorded call. +/// Represents a recorded log that is emitted during a trace call. #[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] pub struct CallLogFrame { /// The address of the contract that was called. @@ -56,6 +56,9 @@ pub struct CallLogFrame { /// The data of the log. #[serde(default, skip_serializing_if = "Option::is_none")] pub data: Option, + /// The position of the log relative to subcalls within the same trace. + #[serde(default, with = "alloy_serde::quantity::opt", skip_serializing_if = "Option::is_none")] + pub position: Option, } /// The configuration for the call tracer. diff --git a/crates/rpc-types-trace/test_data/call_tracer/with_log.json b/crates/rpc-types-trace/test_data/call_tracer/with_log.json index 2528bbc0484..818cd72036a 100644 --- a/crates/rpc-types-trace/test_data/call_tracer/with_log.json +++ b/crates/rpc-types-trace/test_data/call_tracer/with_log.json @@ -8,11 +8,12 @@ { "address": "0xf4eced2f682ce333f96f2d8966c613ded8fc95dd", "topics": [ - "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", - "0x000000000000000000000000d1220a0cf47c7b9be7a2e6ba89f429762e7b9adb", - "0x000000000000000000000000dbf03b407c01e7cd3cbea99509d93f8dddc8c6fb" + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x000000000000000000000000d1220a0cf47c7b9be7a2e6ba89f429762e7b9adb", + "0x000000000000000000000000dbf03b407c01e7cd3cbea99509d93f8dddc8c6fb" ], - "data": "0x0000000000000000000000000000000000000000000000000000000000989680" + "data": "0x0000000000000000000000000000000000000000000000000000000000989680", + "position": "0x0" } ], "value": "0x0", From 4a270df340d21359283b3d7fb2c1204baf9f4084 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Mon, 19 Aug 2024 23:42:43 -0700 Subject: [PATCH 082/186] TxEip7702: add payload length methods (#1152) * TxEip7702: add payload length methods * clean up --- crates/consensus/src/transaction/eip7702.rs | 73 ++++++++++++++++++++- 1 file changed, 71 insertions(+), 2 deletions(-) diff --git a/crates/consensus/src/transaction/eip7702.rs b/crates/consensus/src/transaction/eip7702.rs index 2d5221ac2b0..a062aefd28e 100644 --- a/crates/consensus/src/transaction/eip7702.rs +++ b/crates/consensus/src/transaction/eip7702.rs @@ -1,7 +1,7 @@ use crate::{EncodableSignature, SignableTransaction, Signed, Transaction, TxType}; use alloy_eips::eip2930::AccessList; use alloy_primitives::{keccak256, Bytes, ChainId, Signature, TxKind, U256}; -use alloy_rlp::{BufMut, Decodable, Encodable, Header}; +use alloy_rlp::{length_of_length, BufMut, Decodable, Encodable, Header}; use core::mem; #[cfg(not(feature = "std"))] @@ -269,6 +269,19 @@ impl TxEip7702 { self.input.len() + // input self.authorization_list.capacity() * mem::size_of::() // authorization_list } + + /// Output the length of the RLP signed transaction encoding, _without_ a RLP string header. + pub fn payload_len_with_signature_without_header(&self, signature: &Signature) -> usize { + let payload_length = self.fields_len() + signature.rlp_vrs_len(); + // 'transaction type byte length' + 'header length' + 'payload length' + 1 + length_of_length(payload_length) + payload_length + } + + /// Output the length of the RLP signed transaction encoding. This encodes with a RLP header. + pub fn payload_len_with_signature(&self, signature: &Signature) -> usize { + let len = self.payload_len_with_signature_without_header(signature); + length_of_length(len) + len + } } impl Transaction for TxEip7702 { @@ -356,10 +369,66 @@ impl Decodable for TxEip7702 { #[cfg(all(test, feature = "k256"))] mod tests { + use core::str::FromStr; + use super::TxEip7702; use crate::SignableTransaction; use alloy_eips::eip2930::AccessList; - use alloy_primitives::{address, b256, hex, Address, Signature, TxKind, U256}; + use alloy_primitives::{address, b256, hex, Address, Bytes, Signature, TxKind, U256}; + + #[test] + fn test_payload_len_with_signature_without_header() { + let tx = TxEip7702 { + chain_id: 1u64, + nonce: 0, + max_fee_per_gas: 0x4a817c800, + max_priority_fee_per_gas: 0x3b9aca00, + gas_limit: 2, + to: TxKind::Create, + value: U256::ZERO, + input: Bytes::from(vec![1, 2]), + access_list: Default::default(), + authorization_list: Default::default(), + }; + + let signature = Signature::from_rs_and_parity( + U256::from_str("0xc569c92f176a3be1a6352dd5005bfc751dcb32f57623dd2a23693e64bf4447b0") + .unwrap(), + U256::from_str("0x1a891b566d369e79b7a66eecab1e008831e22daa15f91a0a0cf4f9f28f47ee05") + .unwrap(), + 1, + ) + .unwrap(); + + assert_eq!(tx.payload_len_with_signature_without_header(&signature), 91); + } + + #[test] + fn test_payload_len_with_signature() { + let tx = TxEip7702 { + chain_id: 1u64, + nonce: 0, + max_fee_per_gas: 0x4a817c800, + max_priority_fee_per_gas: 0x3b9aca00, + gas_limit: 2, + to: TxKind::Create, + value: U256::ZERO, + input: Bytes::from(vec![1, 2]), + access_list: Default::default(), + authorization_list: Default::default(), + }; + + let signature = Signature::from_rs_and_parity( + U256::from_str("0xc569c92f176a3be1a6352dd5005bfc751dcb32f57623dd2a23693e64bf4447b0") + .unwrap(), + U256::from_str("0x1a891b566d369e79b7a66eecab1e008831e22daa15f91a0a0cf4f9f28f47ee05") + .unwrap(), + 1, + ) + .unwrap(); + + assert_eq!(tx.payload_len_with_signature(&signature), 93); + } #[test] fn encode_decode_eip7702() { From 362eec08c3fdc70c5247d8d03b3c14164307c4a6 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Tue, 20 Aug 2024 15:06:00 +0800 Subject: [PATCH 083/186] fix: remove `OtherFields` from Transaction and Block (#1154) fix: remove other fields from Transaction and Block --- crates/rpc-types-eth/src/block.rs | 7 ------- crates/rpc-types-eth/src/transaction/mod.rs | 8 -------- 2 files changed, 15 deletions(-) diff --git a/crates/rpc-types-eth/src/block.rs b/crates/rpc-types-eth/src/block.rs index 1622b3c74f0..10fbbf26109 100644 --- a/crates/rpc-types-eth/src/block.rs +++ b/crates/rpc-types-eth/src/block.rs @@ -3,7 +3,6 @@ use crate::{ConversionError, Transaction, Withdrawal}; use alloy_network_primitives::BlockTransactions; use alloy_primitives::{Address, BlockHash, Bloom, Bytes, B256, B64, U256}; -use alloy_serde::OtherFields; use serde::{ser::Error, Deserialize, Serialize, Serializer}; use std::{collections::BTreeMap, ops::Deref}; @@ -35,9 +34,6 @@ pub struct Block { /// Withdrawals in the block. #[serde(default, skip_serializing_if = "Option::is_none")] pub withdrawals: Option>, - /// Support for arbitrary additional fields. - #[serde(flatten)] - pub other: OtherFields, } impl Block { @@ -374,7 +370,6 @@ mod tests { transactions: vec![B256::with_last_byte(18)].into(), size: Some(U256::from(19)), withdrawals: Some(vec![]), - other: Default::default(), }; let serialized = serde_json::to_string(&block).unwrap(); assert_eq!( @@ -417,7 +412,6 @@ mod tests { transactions: BlockTransactions::Uncle, size: Some(U256::from(19)), withdrawals: None, - other: Default::default(), }; let serialized = serde_json::to_string(&block).unwrap(); assert_eq!( @@ -460,7 +454,6 @@ mod tests { transactions: vec![B256::with_last_byte(18)].into(), size: Some(U256::from(19)), withdrawals: None, - other: Default::default(), }; let serialized = serde_json::to_string(&block).unwrap(); assert_eq!( diff --git a/crates/rpc-types-eth/src/transaction/mod.rs b/crates/rpc-types-eth/src/transaction/mod.rs index 1e29b7c9283..df121b03569 100644 --- a/crates/rpc-types-eth/src/transaction/mod.rs +++ b/crates/rpc-types-eth/src/transaction/mod.rs @@ -7,7 +7,6 @@ use alloy_consensus::{ use alloy_eips::eip7702::SignedAuthorization; use alloy_network_primitives::TransactionResponse; use alloy_primitives::{Address, BlockHash, Bytes, ChainId, TxHash, TxKind, B256, U256}; -use alloy_serde::OtherFields; use serde::{Deserialize, Serialize}; pub use alloy_consensus::BlobTransactionSidecar; @@ -112,11 +111,6 @@ pub struct Transaction { /// signer desires to execute in the context of their EOA and their signature. #[serde(default, skip_serializing_if = "Option::is_none")] pub authorization_list: Option>, - /// Arbitrary extra fields. - /// - /// This captures fields that are not native to ethereum but included in ethereum adjacent networks, for example fields the [optimism `eth_getTransactionByHash` request](https://docs.alchemy.com/alchemy/apis/optimism/eth-gettransactionbyhash) returns additional fields that this type will capture - #[serde(flatten)] - pub other: OtherFields, } impl Transaction { @@ -378,7 +372,6 @@ mod tests { nonce: 1u64, }) .into_signed(AlloySignature::from_str("48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c8041b").unwrap())]), - other: Default::default(), }; let serialized = serde_json::to_string(&transaction).unwrap(); assert_eq!( @@ -422,7 +415,6 @@ mod tests { nonce: 1u64, }) .into_signed(AlloySignature::from_str("48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c8041b").unwrap())]), - other: Default::default(), }; let serialized = serde_json::to_string(&transaction).unwrap(); assert_eq!( From e81f590d6c512297878e2e0ac911713c609ae7dd Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Tue, 20 Aug 2024 19:12:12 +0200 Subject: [PATCH 084/186] chore: remove async_trait from NetworkWallet (#1160) --- crates/network/src/ethereum/wallet.rs | 3 --- crates/network/src/transaction/signer.rs | 18 +++++++++--------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/crates/network/src/ethereum/wallet.rs b/crates/network/src/ethereum/wallet.rs index 58e462d57eb..aa358ffd884 100644 --- a/crates/network/src/ethereum/wallet.rs +++ b/crates/network/src/ethereum/wallet.rs @@ -2,7 +2,6 @@ use crate::{Network, NetworkWallet, TxSigner}; use alloy_consensus::{SignableTransaction, TxEnvelope, TypedTransaction}; use alloy_primitives::Address; use alloy_signer::Signature; -use async_trait::async_trait; use std::{collections::BTreeMap, sync::Arc}; /// A wallet capable of signing any transaction for the Ethereum network. @@ -95,8 +94,6 @@ impl EthereumWallet { } } -#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] -#[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl NetworkWallet for EthereumWallet where N: Network, diff --git a/crates/network/src/transaction/signer.rs b/crates/network/src/transaction/signer.rs index 0c0b960a974..60780e20eb5 100644 --- a/crates/network/src/transaction/signer.rs +++ b/crates/network/src/transaction/signer.rs @@ -15,8 +15,6 @@ use futures_utils_wasm::impl_future; /// Network wallets are expected to contain one or more signing credentials, /// keyed by signing address. The default signer address should be used when /// no specific signer address is specified. -#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] -#[cfg_attr(not(target_arch = "wasm32"), async_trait)] #[auto_impl(&, &mut, Box, Rc, Arc)] pub trait NetworkWallet: std::fmt::Debug + Send + Sync { /// Get the default signer address. This address should be used @@ -33,11 +31,11 @@ pub trait NetworkWallet: std::fmt::Debug + Send + Sync { /// Asynchronously sign an unsigned transaction, with a specified /// credential. #[doc(alias = "sign_tx_from")] - async fn sign_transaction_from( + fn sign_transaction_from( &self, sender: Address, tx: N::UnsignedTx, - ) -> alloy_signer::Result; + ) -> impl_future!(>); /// Asynchronously sign an unsigned transaction. #[doc(alias = "sign_tx")] @@ -50,13 +48,15 @@ pub trait NetworkWallet: std::fmt::Debug + Send + Sync { /// Asynchronously sign a transaction request, using the sender specified /// in the `from` field. - async fn sign_request( + fn sign_request( &self, request: N::TransactionRequest, - ) -> alloy_signer::Result { - let sender = request.from().unwrap_or_else(|| self.default_signer_address()); - let tx = request.build_unsigned().map_err(alloy_signer::Error::other)?; - self.sign_transaction_from(sender, tx).await + ) -> impl_future!(>) { + async move { + let sender = request.from().unwrap_or_else(|| self.default_signer_address()); + let tx = request.build_unsigned().map_err(alloy_signer::Error::other)?; + self.sign_transaction_from(sender, tx).await + } } } From cab3e081602b602084cc862068b0914e5fc1aead Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Wed, 21 Aug 2024 13:31:14 +0800 Subject: [PATCH 085/186] fix: allow arbitrary strings in subscription ids (#1163) * fix: use json_rpc::Id for subscription id * fix test * SubId --- crates/json-rpc/src/lib.rs | 2 +- crates/json-rpc/src/notification.rs | 19 ++++++++++++++++--- crates/pubsub/src/managers/in_flight.rs | 7 +++---- crates/pubsub/src/managers/req.rs | 5 ++--- crates/pubsub/src/managers/sub.rs | 18 +++++++++--------- crates/pubsub/src/service.rs | 14 ++++++++------ 6 files changed, 39 insertions(+), 26 deletions(-) diff --git a/crates/json-rpc/src/lib.rs b/crates/json-rpc/src/lib.rs index 5d49caf38bd..c705b72e7ba 100644 --- a/crates/json-rpc/src/lib.rs +++ b/crates/json-rpc/src/lib.rs @@ -86,7 +86,7 @@ mod error; pub use error::RpcError; mod notification; -pub use notification::{EthNotification, PubSubItem}; +pub use notification::{EthNotification, PubSubItem, SubId}; mod packet; pub use packet::{BorrowedResponsePacket, RequestPacket, ResponsePacket}; diff --git a/crates/json-rpc/src/notification.rs b/crates/json-rpc/src/notification.rs index 40aab2265ee..743f5a2dc34 100644 --- a/crates/json-rpc/src/notification.rs +++ b/crates/json-rpc/src/notification.rs @@ -5,12 +5,22 @@ use serde::{ Deserialize, Serialize, }; +/// A subscription ID. +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize, PartialOrd, Ord)] +#[serde(untagged)] +pub enum SubId { + /// A number. + Number(U256), + /// A string. + String(String), +} + /// An ethereum-style notification, not to be confused with a JSON-RPC /// notification. #[derive(Clone, Debug, Serialize, Deserialize)] pub struct EthNotification> { /// The subscription ID. - pub subscription: U256, + pub subscription: SubId, /// The notification payload. pub result: T, } @@ -128,7 +138,7 @@ impl<'de> Deserialize<'de> for PubSubItem { #[cfg(test)] mod test { - use crate::{EthNotification, PubSubItem}; + use crate::{EthNotification, PubSubItem, SubId}; #[test] fn deserializer_test() { @@ -140,7 +150,10 @@ mod test { match deser { PubSubItem::Notification(EthNotification { subscription, result }) => { - assert_eq!(subscription, "0xcd0c3e8af590364c09d0fa6a1210faf5".parse().unwrap()); + assert_eq!( + subscription, + SubId::Number("0xcd0c3e8af590364c09d0fa6a1210faf5".parse().unwrap()) + ); assert_eq!(result.get(), r#"{"difficulty": "0xd9263f42a87", "uncles": []}"#); } _ => panic!("unexpected deserialization result"), diff --git a/crates/pubsub/src/managers/in_flight.rs b/crates/pubsub/src/managers/in_flight.rs index acc73e8e952..122b09f6455 100644 --- a/crates/pubsub/src/managers/in_flight.rs +++ b/crates/pubsub/src/managers/in_flight.rs @@ -1,5 +1,4 @@ -use alloy_json_rpc::{Response, ResponsePayload, SerializedRequest}; -use alloy_primitives::U256; +use alloy_json_rpc::{Response, ResponsePayload, SerializedRequest, SubId}; use alloy_transport::{TransportError, TransportResult}; use std::fmt; use tokio::sync::oneshot; @@ -55,10 +54,10 @@ impl InFlight { /// Fulfill the request with a response. This consumes the in-flight /// request. If the request is a subscription and the response is not an /// error, the subscription ID and the in-flight request are returned. - pub(crate) fn fulfill(self, resp: Response) -> Option<(U256, Self)> { + pub(crate) fn fulfill(self, resp: Response) -> Option<(SubId, Self)> { if self.is_subscription() { if let ResponsePayload::Success(val) = resp.payload { - let sub_id: serde_json::Result = serde_json::from_str(val.get()); + let sub_id: serde_json::Result = serde_json::from_str(val.get()); return match sub_id { Ok(alias) => Some((alias, self)), Err(e) => { diff --git a/crates/pubsub/src/managers/req.rs b/crates/pubsub/src/managers/req.rs index 15b3c306900..e21eb4f7c70 100644 --- a/crates/pubsub/src/managers/req.rs +++ b/crates/pubsub/src/managers/req.rs @@ -1,6 +1,5 @@ use crate::managers::InFlight; -use alloy_json_rpc::{Id, Response}; -use alloy_primitives::U256; +use alloy_json_rpc::{Id, Response, SubId}; use std::collections::BTreeMap; /// Manages in-flight requests. @@ -30,7 +29,7 @@ impl RequestManager { /// If the request created a new subscription, this function returns the /// subscription ID and the in-flight request for conversion to an /// `ActiveSubscription`. - pub(crate) fn handle_response(&mut self, resp: Response) -> Option<(U256, InFlight)> { + pub(crate) fn handle_response(&mut self, resp: Response) -> Option<(SubId, InFlight)> { if let Some(in_flight) = self.reqs.remove(&resp.id) { return in_flight.fulfill(resp); } diff --git a/crates/pubsub/src/managers/sub.rs b/crates/pubsub/src/managers/sub.rs index a3c872d109b..6081541d83d 100644 --- a/crates/pubsub/src/managers/sub.rs +++ b/crates/pubsub/src/managers/sub.rs @@ -1,6 +1,6 @@ use crate::{managers::ActiveSubscription, RawSubscription}; -use alloy_json_rpc::{EthNotification, SerializedRequest}; -use alloy_primitives::{B256, U256}; +use alloy_json_rpc::{EthNotification, SerializedRequest, SubId}; +use alloy_primitives::B256; use bimap::BiBTreeMap; #[derive(Debug, Default)] @@ -8,7 +8,7 @@ pub(crate) struct SubscriptionManager { /// The subscriptions. local_to_sub: BiBTreeMap, /// Tracks the CURRENT server id for a subscription. - local_to_server: BiBTreeMap, + local_to_server: BiBTreeMap, } impl SubscriptionManager { @@ -26,7 +26,7 @@ impl SubscriptionManager { fn insert( &mut self, request: SerializedRequest, - server_id: U256, + server_id: SubId, channel_size: usize, ) -> RawSubscription { let active = ActiveSubscription::new(request, channel_size); @@ -43,7 +43,7 @@ impl SubscriptionManager { pub(crate) fn upsert( &mut self, request: SerializedRequest, - server_id: U256, + server_id: SubId, channel_size: usize, ) -> RawSubscription { let local_id = request.params_hash(); @@ -59,8 +59,8 @@ impl SubscriptionManager { } /// De-alias an alias, getting the original ID. - pub(crate) fn local_id_for(&self, server_id: U256) -> Option { - self.local_to_server.get_by_right(&server_id).copied() + pub(crate) fn local_id_for(&self, server_id: &SubId) -> Option { + self.local_to_server.get_by_right(server_id).copied() } /// Drop all server_ids. @@ -69,7 +69,7 @@ impl SubscriptionManager { } /// Change the server_id of a subscription. - fn change_server_id(&mut self, local_id: B256, server_id: U256) { + fn change_server_id(&mut self, local_id: B256, server_id: SubId) { self.local_to_server.insert(local_id, server_id); } @@ -83,7 +83,7 @@ impl SubscriptionManager { /// and if any receiver exists. If the sub id is unknown, or no receiver /// exists, the notification is dropped. pub(crate) fn notify(&mut self, notification: EthNotification) { - if let Some(local_id) = self.local_id_for(notification.subscription) { + if let Some(local_id) = self.local_id_for(¬ification.subscription) { if let Some((_, mut sub)) = self.local_to_sub.remove_by_left(&local_id) { sub.notify(notification.result); self.local_to_sub.insert(local_id, sub); diff --git a/crates/pubsub/src/service.rs b/crates/pubsub/src/service.rs index e2d164c7dc7..afd503e4e40 100644 --- a/crates/pubsub/src/service.rs +++ b/crates/pubsub/src/service.rs @@ -4,7 +4,7 @@ use crate::{ managers::{InFlight, RequestManager, SubscriptionManager}, PubSubConnect, PubSubFrontend, RawSubscription, }; -use alloy_json_rpc::{Id, PubSubItem, Request, Response, ResponsePayload}; +use alloy_json_rpc::{Id, PubSubItem, Request, Response, ResponsePayload, SubId}; use alloy_primitives::U256; use alloy_transport::{ utils::{to_json_raw_value, Spawnable}, @@ -167,16 +167,18 @@ impl PubSubService { } /// Rewrite the subscription id and insert into the subscriptions manager - fn handle_sub_response(&mut self, in_flight: InFlight, server_id: U256) -> TransportResult<()> { + fn handle_sub_response( + &mut self, + in_flight: InFlight, + server_id: SubId, + ) -> TransportResult<()> { let request = in_flight.request; let id = request.id().clone(); - self.subs.upsert(request, server_id, in_flight.channel_size); + let sub = self.subs.upsert(request, server_id, in_flight.channel_size); - // lie to the client about the sub id. - let local_id = self.subs.local_id_for(server_id).unwrap(); // Serialized B256 is always a valid serialized U256 too. - let ser_alias = to_json_raw_value(&local_id)?; + let ser_alias = to_json_raw_value(sub.local_id())?; // We send back a success response with the new subscription ID. // We don't care if the channel is dead. From e63da6fbab9b03b0712a7f9ef57a2345bff44ae7 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 21 Aug 2024 09:36:21 +0200 Subject: [PATCH 086/186] feat: add get raw transaction by hash (#1168) --- crates/provider/src/provider/trait.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/crates/provider/src/provider/trait.rs b/crates/provider/src/provider/trait.rs index 3515440e5df..ffed51cce8c 100644 --- a/crates/provider/src/provider/trait.rs +++ b/crates/provider/src/provider/trait.rs @@ -519,6 +519,18 @@ pub trait Provider: self.client().request("eth_getTransactionByHash", (hash,)).await } + /// Returns the EIP-2718 encoded transaction if it exists, see also + /// [Decodable2718](alloy_eips::eip2718::Decodable2718). + /// + /// If the transaction is an EIP-4844 transaction that is still in the pool (pending) it will + /// include the sidecar, otherwise it will the consensus variant without the sidecar: + /// [TxEip4844](alloy_consensus::transaction::eip4844::TxEip4844). + /// + /// This can be decoded into [TxEnvelope](alloy_consensus::transaction::TxEnvelope). + async fn get_raw_transaction_by_hash(&self, hash: TxHash) -> TransportResult> { + self.client().request("eth_getRawTransactionByHash", (hash,)).await + } + /// Gets the transaction count (AKA "nonce") of the corresponding address. #[doc(alias = "get_nonce")] #[doc(alias = "get_account_nonce")] From b91ba0e6f31c526947a7425130f9796f6bb5a536 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Thu, 22 Aug 2024 11:22:27 +0800 Subject: [PATCH 087/186] feat: network-parameterized block responses (#1106) * feat: network-parameterized block responses * extend header trait * rm options * fix tests --- crates/network-primitives/src/lib.rs | 2 +- crates/network-primitives/src/traits.rs | 76 +++++++++++++++++++++++++ crates/network/src/any/mod.rs | 6 +- crates/network/src/ethereum/mod.rs | 2 + crates/network/src/lib.rs | 7 ++- crates/provider/src/chain.rs | 2 +- crates/provider/src/ext/anvil.rs | 2 +- crates/provider/src/fillers/gas.rs | 3 +- crates/provider/src/heart.rs | 2 +- crates/provider/src/provider/trait.rs | 44 +++++++------- crates/rpc-types-eth/src/block.rs | 53 ++++++++++++++--- 11 files changed, 164 insertions(+), 35 deletions(-) diff --git a/crates/network-primitives/src/lib.rs b/crates/network-primitives/src/lib.rs index 42f43f134ef..d1534307e4a 100644 --- a/crates/network-primitives/src/lib.rs +++ b/crates/network-primitives/src/lib.rs @@ -7,7 +7,7 @@ #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] mod traits; -pub use traits::{ReceiptResponse, TransactionResponse}; +pub use traits::{BlockResponse, HeaderResponse, ReceiptResponse, TransactionResponse}; mod block; pub use block::{BlockTransactionHashes, BlockTransactions, BlockTransactionsKind}; diff --git a/crates/network-primitives/src/traits.rs b/crates/network-primitives/src/traits.rs index 9580f19b584..c7409a85be8 100644 --- a/crates/network-primitives/src/traits.rs +++ b/crates/network-primitives/src/traits.rs @@ -1,6 +1,8 @@ use alloy_primitives::{Address, BlockHash, Bytes, TxHash, U256}; use alloy_serde::WithOtherFields; +use crate::BlockTransactions; + /// Receipt JSON-RPC response. pub trait ReceiptResponse { /// Address of the created contract, or `None` if the transaction was not a deployment. @@ -46,6 +48,41 @@ pub trait TransactionResponse { fn input(&self) -> &Bytes; } +/// Header JSON-RPC response. +pub trait HeaderResponse { + /// Block number + fn number(&self) -> u64; + + /// Block timestamp + fn timestamp(&self) -> u64; + + /// Extra data + fn extra_data(&self) -> &Bytes; + + /// Base fee per unit of gas (If EIP-1559 is supported) + fn base_fee_per_gas(&self) -> Option; + + /// Blob fee for the next block (if EIP-4844 is supported) + fn next_block_blob_fee(&self) -> Option; +} + +/// Block JSON-RPC response. +pub trait BlockResponse { + /// Header type + type Header; + /// Transaction type + type Transaction; + + /// Block header + fn header(&self) -> &Self::Header; + + /// Block transactions + fn transactions(&self) -> &BlockTransactions; + + /// Mutable reference to block transactions + fn transactions_mut(&mut self) -> &mut BlockTransactions; +} + impl TransactionResponse for WithOtherFields { fn tx_hash(&self) -> TxHash { self.inner.tx_hash() @@ -89,3 +126,42 @@ impl ReceiptResponse for WithOtherFields { self.inner.block_number() } } + +impl BlockResponse for WithOtherFields { + type Header = T::Header; + type Transaction = T::Transaction; + + fn header(&self) -> &Self::Header { + self.inner.header() + } + + fn transactions(&self) -> &BlockTransactions { + self.inner.transactions() + } + + fn transactions_mut(&mut self) -> &mut BlockTransactions { + self.inner.transactions_mut() + } +} + +impl HeaderResponse for WithOtherFields { + fn number(&self) -> u64 { + self.inner.number() + } + + fn timestamp(&self) -> u64 { + self.inner.timestamp() + } + + fn extra_data(&self) -> &Bytes { + self.inner.extra_data() + } + + fn base_fee_per_gas(&self) -> Option { + self.inner.base_fee_per_gas() + } + + fn next_block_blob_fee(&self) -> Option { + self.inner.next_block_blob_fee() + } +} diff --git a/crates/network/src/any/mod.rs b/crates/network/src/any/mod.rs index 8103b562ca2..6e1b2cab832 100644 --- a/crates/network/src/any/mod.rs +++ b/crates/network/src/any/mod.rs @@ -1,7 +1,7 @@ use crate::Network; use alloy_consensus::TxType; use alloy_eips::eip2718::Eip2718Error; -use alloy_rpc_types_eth::{AnyTransactionReceipt, Header, Transaction, TransactionRequest}; +use alloy_rpc_types_eth::{AnyTransactionReceipt, Block, Header, Transaction, TransactionRequest}; use alloy_serde::WithOtherFields; use core::fmt; @@ -73,5 +73,7 @@ impl Network for AnyNetwork { type ReceiptResponse = AnyTransactionReceipt; - type HeaderResponse = WithOtherFields
; + type HeaderResponse = Header; + + type BlockResponse = WithOtherFields>; } diff --git a/crates/network/src/ethereum/mod.rs b/crates/network/src/ethereum/mod.rs index 0d2266874e4..ff751cea0bf 100644 --- a/crates/network/src/ethereum/mod.rs +++ b/crates/network/src/ethereum/mod.rs @@ -29,4 +29,6 @@ impl Network for Ethereum { type ReceiptResponse = alloy_rpc_types_eth::TransactionReceipt; type HeaderResponse = alloy_rpc_types_eth::Header; + + type BlockResponse = alloy_rpc_types_eth::Block; } diff --git a/crates/network/src/lib.rs b/crates/network/src/lib.rs index 55a931ed40f..13f0706327d 100644 --- a/crates/network/src/lib.rs +++ b/crates/network/src/lib.rs @@ -9,6 +9,7 @@ use alloy_consensus::TxReceipt; use alloy_eips::eip2718::{Eip2718Envelope, Eip2718Error}; use alloy_json_rpc::RpcObject; +use alloy_network_primitives::{BlockResponse, HeaderResponse}; use core::fmt::{Debug, Display}; mod transaction; @@ -85,5 +86,9 @@ pub trait Network: Debug + Clone + Copy + Sized + Send + Sync + 'static { type ReceiptResponse: RpcObject + ReceiptResponse; /// The JSON body of a header response. - type HeaderResponse: RpcObject; + type HeaderResponse: RpcObject + HeaderResponse; + + /// The JSON body of a block response. + type BlockResponse: RpcObject + + BlockResponse; } diff --git a/crates/provider/src/chain.rs b/crates/provider/src/chain.rs index 7dd89f5d960..d0149ba328a 100644 --- a/crates/provider/src/chain.rs +++ b/crates/provider/src/chain.rs @@ -161,7 +161,7 @@ mod tests { provider.anvil_mine(Some(U256::from(1)), None).await.unwrap(); let block = with_timeout(stream.next()).await.expect("Block wasn't fetched"); - assert_eq!(block.header.number, Some(1u64)); + assert_eq!(block.header.number, 1); } #[tokio::test] diff --git a/crates/provider/src/ext/anvil.rs b/crates/provider/src/ext/anvil.rs index e3719e64ab1..05a0dff61b3 100644 --- a/crates/provider/src/ext/anvil.rs +++ b/crates/provider/src/ext/anvil.rs @@ -652,7 +652,7 @@ mod tests { let node_info = provider.anvil_node_info().await.unwrap(); - assert_eq!(node_info.current_block_number, latest_block.header.number.unwrap() + 1); + assert_eq!(node_info.current_block_number, latest_block.header.number + 1); } #[tokio::test] diff --git a/crates/provider/src/fillers/gas.rs b/crates/provider/src/fillers/gas.rs index 756e54d59be..422c750ab0a 100644 --- a/crates/provider/src/fillers/gas.rs +++ b/crates/provider/src/fillers/gas.rs @@ -8,6 +8,7 @@ use crate::{ }; use alloy_json_rpc::RpcError; use alloy_network::{Network, TransactionBuilder}; +use alloy_network_primitives::{BlockResponse, HeaderResponse}; use alloy_rpc_types_eth::BlockNumberOrTag; use alloy_transport::{Transport, TransportResult}; use futures::FutureExt; @@ -150,7 +151,7 @@ impl GasFiller { .get_block_by_number(BlockNumberOrTag::Latest, false) .await? .ok_or(RpcError::NullResp)? - .header + .header() .next_block_blob_fee() .ok_or(RpcError::UnsupportedFeature("eip4844")) } diff --git a/crates/provider/src/heart.rs b/crates/provider/src/heart.rs index d7f044530fb..247c7201c4e 100644 --- a/crates/provider/src/heart.rs +++ b/crates/provider/src/heart.rs @@ -563,7 +563,7 @@ impl Heartbeat { /// the latest block. fn handle_new_block(&mut self, block: Block, latest: &watch::Sender>) { // Blocks without numbers are ignored, as they're not part of the chain. - let Some(block_height) = &block.header.number else { return }; + let block_height = &block.header.number; // Add the block the lookbehind. // The value is chosen arbitrarily to not have a huge memory footprint but still diff --git a/crates/provider/src/provider/trait.rs b/crates/provider/src/provider/trait.rs index ffed51cce8c..00d61a1b5ca 100644 --- a/crates/provider/src/provider/trait.rs +++ b/crates/provider/src/provider/trait.rs @@ -9,15 +9,17 @@ use crate::{ use alloy_eips::eip2718::Encodable2718; use alloy_json_rpc::{RpcError, RpcParam, RpcReturn}; use alloy_network::{Ethereum, Network}; -use alloy_network_primitives::{BlockTransactionsKind, ReceiptResponse}; +use alloy_network_primitives::{ + BlockResponse, BlockTransactionsKind, HeaderResponse, ReceiptResponse, +}; use alloy_primitives::{ hex, Address, BlockHash, BlockNumber, Bytes, StorageKey, StorageValue, TxHash, B256, U128, U256, U64, }; use alloy_rpc_client::{ClientRef, PollerBuilder, RpcCall, WeakClient}; use alloy_rpc_types_eth::{ - AccessListResult, Block, BlockId, BlockNumberOrTag, EIP1186AccountProofResponse, FeeHistory, - Filter, FilterChanges, Log, SyncStatus, + AccessListResult, BlockId, BlockNumberOrTag, EIP1186AccountProofResponse, FeeHistory, Filter, + FilterChanges, Log, SyncStatus, }; use alloy_transport::{BoxTransport, Transport, TransportResult}; use serde_json::value::RawValue; @@ -213,8 +215,8 @@ pub trait Provider: self.get_block_by_number(BlockNumberOrTag::Latest, false) .await? .ok_or(RpcError::NullResp)? - .header - .base_fee_per_gas + .header() + .base_fee_per_gas() .ok_or(RpcError::UnsupportedFeature("eip1559"))? } }; @@ -262,7 +264,7 @@ pub trait Provider: &self, block: BlockId, kind: BlockTransactionsKind, - ) -> TransportResult> { + ) -> TransportResult> { match block { BlockId::Hash(hash) => self.get_block_by_hash(hash.into(), kind).await, BlockId::Number(number) => { @@ -277,7 +279,7 @@ pub trait Provider: &self, hash: BlockHash, kind: BlockTransactionsKind, - ) -> TransportResult> { + ) -> TransportResult> { let full = match kind { BlockTransactionsKind::Full => true, BlockTransactionsKind::Hashes => false, @@ -285,13 +287,13 @@ pub trait Provider: let block = self .client() - .request::<_, Option>("eth_getBlockByHash", (hash, full)) + .request::<_, Option>("eth_getBlockByHash", (hash, full)) .await? .map(|mut block| { if !full { // this ensures an empty response for `Hashes` has the expected form // this is required because deserializing [] is ambiguous - block.transactions.convert_to_hashes(); + block.transactions_mut().convert_to_hashes(); } block }); @@ -305,16 +307,16 @@ pub trait Provider: &self, number: BlockNumberOrTag, hydrate: bool, - ) -> TransportResult> { + ) -> TransportResult> { let block = self .client() - .request::<_, Option>("eth_getBlockByNumber", (number, hydrate)) + .request::<_, Option>("eth_getBlockByNumber", (number, hydrate)) .await? .map(|mut block| { if !hydrate { // this ensures an empty response for `Hashes` has the expected form // this is required because deserializing [] is ambiguous - block.transactions.convert_to_hashes(); + block.transactions_mut().convert_to_hashes(); } block }); @@ -548,7 +550,7 @@ pub trait Provider: } /// Gets an uncle block through the tag [BlockId] and index [u64]. - async fn get_uncle(&self, tag: BlockId, idx: u64) -> TransportResult> { + async fn get_uncle(&self, tag: BlockId, idx: u64) -> TransportResult> { let idx = U64::from(idx); match tag { BlockId::Hash(hash) => { @@ -725,7 +727,9 @@ pub trait Provider: /// # } /// ``` #[cfg(feature = "pubsub")] - async fn subscribe_blocks(&self) -> TransportResult> { + async fn subscribe_blocks( + &self, + ) -> TransportResult> { self.root().pubsub_frontend()?; let id = self.client().request("eth_subscribe", ("newHeads",)).await?; self.root().get_subscription(id).await @@ -1007,7 +1011,7 @@ mod tests { use alloy_network::AnyNetwork; use alloy_node_bindings::Anvil; use alloy_primitives::{address, b256, bytes, keccak256}; - use alloy_rpc_types_eth::request::TransactionRequest; + use alloy_rpc_types_eth::{request::TransactionRequest, Block}; fn init_tracing() { let _ = tracing_subscriber::fmt::try_init(); @@ -1119,7 +1123,7 @@ mod tests { let mut stream = sub.into_stream().take(2); let mut n = 1; while let Some(block) = stream.next().await { - assert_eq!(block.header.number.unwrap(), n); + assert_eq!(block.header.number, n); assert_eq!(block.transactions.hashes().len(), 0); n += 1; } @@ -1141,7 +1145,7 @@ mod tests { let mut stream = sub.into_stream().take(2); let mut n = 1; while let Some(block) = stream.next().await { - assert_eq!(block.header.number.unwrap(), n); + assert_eq!(block.header.number, n); assert_eq!(block.transactions.hashes().len(), 0); n += 1; } @@ -1161,7 +1165,7 @@ mod tests { let mut stream = sub.into_stream().take(1); while let Some(block) = stream.next().await { println!("New block {:?}", block); - assert!(block.header.number.unwrap() > 0); + assert!(block.header.number > 0); } } @@ -1299,7 +1303,7 @@ mod tests { let num = 0; let tag: BlockNumberOrTag = num.into(); let block = provider.get_block_by_number(tag, true).await.unwrap().unwrap(); - assert_eq!(block.header.number.unwrap(), num); + assert_eq!(block.header.number, num); } #[tokio::test] @@ -1309,7 +1313,7 @@ mod tests { let num = 0; let tag: BlockNumberOrTag = num.into(); let block = provider.get_block_by_number(tag, true).await.unwrap().unwrap(); - assert_eq!(block.header.number.unwrap(), num); + assert_eq!(block.header.number, num); } #[tokio::test] diff --git a/crates/rpc-types-eth/src/block.rs b/crates/rpc-types-eth/src/block.rs index 10fbbf26109..2660f138a3f 100644 --- a/crates/rpc-types-eth/src/block.rs +++ b/crates/rpc-types-eth/src/block.rs @@ -1,7 +1,7 @@ //! Block RPC types. use crate::{ConversionError, Transaction, Withdrawal}; -use alloy_network_primitives::BlockTransactions; +use alloy_network_primitives::{BlockResponse, BlockTransactions, HeaderResponse}; use alloy_primitives::{Address, BlockHash, Bloom, Bytes, B256, B64, U256}; use serde::{ser::Error, Deserialize, Serialize, Serializer}; use std::{collections::BTreeMap, ops::Deref}; @@ -68,8 +68,8 @@ pub struct Header { /// Difficulty pub difficulty: U256, /// Block number - #[serde(default, with = "alloy_serde::quantity::opt")] - pub number: Option, + #[serde(with = "alloy_serde::quantity")] + pub number: u64, /// Gas Limit #[serde(default, with = "alloy_serde::quantity")] pub gas_limit: u128, @@ -185,7 +185,7 @@ impl TryFrom
for alloy_consensus::Header { withdrawals_root, logs_bloom, difficulty, - number: number.ok_or(ConversionError::MissingBlockNumber)?, + number, gas_limit, gas_used, timestamp, @@ -201,6 +201,28 @@ impl TryFrom
for alloy_consensus::Header { } } +impl HeaderResponse for Header { + fn number(&self) -> u64 { + self.number + } + + fn timestamp(&self) -> u64 { + self.timestamp + } + + fn extra_data(&self) -> &Bytes { + &self.extra_data + } + + fn base_fee_per_gas(&self) -> Option { + self.base_fee_per_gas + } + + fn next_block_blob_fee(&self) -> Option { + self.next_block_blob_fee() + } +} + /// Error that can occur when converting other types to blocks #[derive(Clone, Copy, Debug, thiserror::Error)] pub enum BlockError { @@ -312,6 +334,23 @@ pub struct BlockOverrides { pub block_hash: Option>, } +impl BlockResponse for Block { + type Transaction = T; + type Header = Header; + + fn header(&self) -> &Self::Header { + &self.header + } + + fn transactions(&self) -> &BlockTransactions { + &self.transactions + } + + fn transactions_mut(&mut self) -> &mut BlockTransactions { + &mut self.transactions + } +} + #[cfg(test)] mod tests { use alloy_primitives::keccak256; @@ -350,7 +389,7 @@ mod tests { transactions_root: B256::with_last_byte(6), receipts_root: B256::with_last_byte(7), withdrawals_root: Some(B256::with_last_byte(8)), - number: Some(9), + number: 9, gas_used: 10, gas_limit: 11, extra_data: vec![1, 2, 3].into(), @@ -392,7 +431,7 @@ mod tests { transactions_root: B256::with_last_byte(6), receipts_root: B256::with_last_byte(7), withdrawals_root: Some(B256::with_last_byte(8)), - number: Some(9), + number: 9, gas_used: 10, gas_limit: 11, extra_data: vec![1, 2, 3].into(), @@ -434,7 +473,7 @@ mod tests { transactions_root: B256::with_last_byte(6), receipts_root: B256::with_last_byte(7), withdrawals_root: None, - number: Some(9), + number: 9, gas_used: 10, gas_limit: 11, extra_data: vec![1, 2, 3].into(), From 3952a72346ff208c12fc0556a3547727aa9c7864 Mon Sep 17 00:00:00 2001 From: nk_ysg Date: Thu, 22 Aug 2024 14:51:30 +0800 Subject: [PATCH 088/186] update TxType comment (#1175) --- crates/consensus/src/transaction/envelope.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/consensus/src/transaction/envelope.rs b/crates/consensus/src/transaction/envelope.rs index 90ee3693838..50d12159ca9 100644 --- a/crates/consensus/src/transaction/envelope.rs +++ b/crates/consensus/src/transaction/envelope.rs @@ -7,13 +7,14 @@ use alloy_rlp::{Decodable, Encodable, Header}; use crate::transaction::eip4844::{TxEip4844, TxEip4844Variant, TxEip4844WithSidecar}; -/// Ethereum `TransactionType` flags as specified in EIPs [2718], [1559], and -/// [2930]. +/// Ethereum `TransactionType` flags as specified in EIPs [2718], [1559], [2930], +/// [4844], and [7702]. /// /// [2718]: https://eips.ethereum.org/EIPS/eip-2718 /// [1559]: https://eips.ethereum.org/EIPS/eip-1559 /// [2930]: https://eips.ethereum.org/EIPS/eip-2930 /// [4844]: https://eips.ethereum.org/EIPS/eip-4844 +/// [7702]: https://eips.ethereum.org/EIPS/eip-7702 #[repr(u8)] #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[doc(alias = "TransactionType")] From e03739402f018440a60c4ead69f687e5507a062e Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Thu, 22 Aug 2024 22:05:28 +0200 Subject: [PATCH 089/186] Add trait methods for constructing `alloy_rpc_types_eth::Transaction` to `alloy_consensus::Transaction` (#1172) * Add trait methods to alloy_consensus::Transaction needed for reth integration * Implement alloy_consensus::Transaction gas trait methods * Implement alloy_consensus::Transaction tx type trait method * fixup! Implement alloy_consensus::Transaction gas trait methods * fixup! Implement alloy_consensus::Transaction tx type trait method * Implement alloy_consensus::Transaction access list trait method * Implement alloy_consensus::Transaction blob versioned hashes trait method * Implement alloy_consensus::Transaction effective tip per gas as default trait method * Remove alloy_consensus::Transaction::hash in favour of using alloy_consensus::Signed * Impl no-std support * Fix lint * Return slice instead of vec * Fix docs Co-authored-by: Arsenii Kulikov --------- Co-authored-by: Arsenii Kulikov --- crates/consensus/src/transaction/eip1559.rs | 26 +++++- crates/consensus/src/transaction/eip2930.rs | 26 +++++- crates/consensus/src/transaction/eip4844.rs | 87 ++++++++++++++++++++ crates/consensus/src/transaction/eip7702.rs | 26 +++++- crates/consensus/src/transaction/envelope.rs | 67 ++++++++++++++- crates/consensus/src/transaction/legacy.rs | 33 +++++++- crates/consensus/src/transaction/mod.rs | 55 +++++++++++++ crates/consensus/src/transaction/typed.rs | 67 ++++++++++++++- 8 files changed, 379 insertions(+), 8 deletions(-) diff --git a/crates/consensus/src/transaction/eip1559.rs b/crates/consensus/src/transaction/eip1559.rs index 9016095e4e2..1777e661ab3 100644 --- a/crates/consensus/src/transaction/eip1559.rs +++ b/crates/consensus/src/transaction/eip1559.rs @@ -1,6 +1,6 @@ use crate::{EncodableSignature, SignableTransaction, Signed, Transaction, TxType}; use alloy_eips::eip2930::AccessList; -use alloy_primitives::{keccak256, Bytes, ChainId, Signature, TxKind, U256}; +use alloy_primitives::{keccak256, Bytes, ChainId, Signature, TxKind, B256, U256}; use alloy_rlp::{BufMut, Decodable, Encodable, Header}; use core::mem; @@ -278,6 +278,18 @@ impl Transaction for TxEip1559 { None } + fn max_fee_per_gas(&self) -> u128 { + self.max_fee_per_gas + } + + fn max_priority_fee_per_gas(&self) -> Option { + Some(self.max_priority_fee_per_gas) + } + + fn priority_fee_or_price(&self) -> u128 { + self.max_priority_fee_per_gas + } + fn to(&self) -> TxKind { self.to } @@ -289,6 +301,18 @@ impl Transaction for TxEip1559 { fn input(&self) -> &[u8] { &self.input } + + fn ty(&self) -> u8 { + TxType::Eip2930 as u8 + } + + fn access_list(&self) -> Option<&AccessList> { + Some(&self.access_list) + } + + fn blob_versioned_hashes(&self) -> Option<&[B256]> { + None + } } impl SignableTransaction for TxEip1559 { diff --git a/crates/consensus/src/transaction/eip2930.rs b/crates/consensus/src/transaction/eip2930.rs index bffebce22f2..4cfbeb615dd 100644 --- a/crates/consensus/src/transaction/eip2930.rs +++ b/crates/consensus/src/transaction/eip2930.rs @@ -1,6 +1,6 @@ use crate::{EncodableSignature, SignableTransaction, Signed, Transaction, TxType}; use alloy_eips::eip2930::AccessList; -use alloy_primitives::{keccak256, Bytes, ChainId, Signature, TxKind, U256}; +use alloy_primitives::{keccak256, Bytes, ChainId, Signature, TxKind, B256, U256}; use alloy_rlp::{length_of_length, BufMut, Decodable, Encodable, Header}; use core::mem; @@ -242,6 +242,18 @@ impl Transaction for TxEip2930 { Some(self.gas_price) } + fn max_fee_per_gas(&self) -> u128 { + self.gas_price + } + + fn max_priority_fee_per_gas(&self) -> Option { + None + } + + fn priority_fee_or_price(&self) -> u128 { + self.gas_price + } + fn to(&self) -> TxKind { self.to } @@ -253,6 +265,18 @@ impl Transaction for TxEip2930 { fn input(&self) -> &[u8] { &self.input } + + fn ty(&self) -> u8 { + TxType::Eip2930 as u8 + } + + fn access_list(&self) -> Option<&AccessList> { + Some(&self.access_list) + } + + fn blob_versioned_hashes(&self) -> Option<&[B256]> { + None + } } impl SignableTransaction for TxEip2930 { diff --git a/crates/consensus/src/transaction/eip4844.rs b/crates/consensus/src/transaction/eip4844.rs index 95f92c5a291..c239a12ea59 100644 --- a/crates/consensus/src/transaction/eip4844.rs +++ b/crates/consensus/src/transaction/eip4844.rs @@ -216,6 +216,27 @@ impl Transaction for TxEip4844Variant { None } + fn max_fee_per_gas(&self) -> u128 { + match self { + Self::TxEip4844(tx) => tx.max_fee_per_gas(), + Self::TxEip4844WithSidecar(tx) => tx.max_fee_per_gas(), + } + } + + fn max_priority_fee_per_gas(&self) -> Option { + match self { + Self::TxEip4844(tx) => tx.max_priority_fee_per_gas(), + Self::TxEip4844WithSidecar(tx) => tx.max_priority_fee_per_gas(), + } + } + + fn priority_fee_or_price(&self) -> u128 { + match self { + Self::TxEip4844(tx) => tx.priority_fee_or_price(), + Self::TxEip4844WithSidecar(tx) => tx.priority_fee_or_price(), + } + } + fn to(&self) -> TxKind { match self { Self::TxEip4844(tx) => tx.to, @@ -237,6 +258,24 @@ impl Transaction for TxEip4844Variant { Self::TxEip4844WithSidecar(tx) => tx.tx().input.as_ref(), } } + + fn ty(&self) -> u8 { + TxType::Eip4844 as u8 + } + + fn access_list(&self) -> Option<&AccessList> { + match self { + Self::TxEip4844(tx) => tx.access_list(), + Self::TxEip4844WithSidecar(tx) => tx.access_list(), + } + } + + fn blob_versioned_hashes(&self) -> Option<&[B256]> { + match self { + Self::TxEip4844(tx) => tx.blob_versioned_hashes(), + Self::TxEip4844WithSidecar(tx) => tx.blob_versioned_hashes(), + } + } } impl SignableTransaction for TxEip4844Variant { @@ -649,6 +688,18 @@ impl Transaction for TxEip4844 { None } + fn max_fee_per_gas(&self) -> u128 { + self.max_fee_per_gas + } + + fn max_priority_fee_per_gas(&self) -> Option { + Some(self.max_priority_fee_per_gas) + } + + fn priority_fee_or_price(&self) -> u128 { + self.max_priority_fee_per_gas + } + fn to(&self) -> TxKind { self.to.into() } @@ -660,6 +711,18 @@ impl Transaction for TxEip4844 { fn input(&self) -> &[u8] { &self.input } + + fn ty(&self) -> u8 { + TxType::Eip4844 as u8 + } + + fn access_list(&self) -> Option<&AccessList> { + Some(&self.access_list) + } + + fn blob_versioned_hashes(&self) -> Option<&[B256]> { + Some(&self.blob_versioned_hashes) + } } impl Encodable for TxEip4844 { @@ -890,6 +953,18 @@ impl Transaction for TxEip4844WithSidecar { self.tx.gas_price() } + fn max_fee_per_gas(&self) -> u128 { + self.tx.max_fee_per_gas() + } + + fn max_priority_fee_per_gas(&self) -> Option { + self.tx.max_priority_fee_per_gas() + } + + fn priority_fee_or_price(&self) -> u128 { + self.tx.priority_fee_or_price() + } + fn to(&self) -> TxKind { self.tx.to() } @@ -901,6 +976,18 @@ impl Transaction for TxEip4844WithSidecar { fn input(&self) -> &[u8] { self.tx.input() } + + fn ty(&self) -> u8 { + TxType::Eip4844 as u8 + } + + fn access_list(&self) -> Option<&AccessList> { + Some(&self.tx.access_list) + } + + fn blob_versioned_hashes(&self) -> Option<&[B256]> { + self.tx.blob_versioned_hashes() + } } #[cfg(test)] diff --git a/crates/consensus/src/transaction/eip7702.rs b/crates/consensus/src/transaction/eip7702.rs index a062aefd28e..44bd709b373 100644 --- a/crates/consensus/src/transaction/eip7702.rs +++ b/crates/consensus/src/transaction/eip7702.rs @@ -1,6 +1,6 @@ use crate::{EncodableSignature, SignableTransaction, Signed, Transaction, TxType}; use alloy_eips::eip2930::AccessList; -use alloy_primitives::{keccak256, Bytes, ChainId, Signature, TxKind, U256}; +use alloy_primitives::{keccak256, Bytes, ChainId, Signature, TxKind, B256, U256}; use alloy_rlp::{length_of_length, BufMut, Decodable, Encodable, Header}; use core::mem; @@ -301,6 +301,18 @@ impl Transaction for TxEip7702 { None } + fn max_fee_per_gas(&self) -> u128 { + self.max_fee_per_gas + } + + fn max_priority_fee_per_gas(&self) -> Option { + Some(self.max_priority_fee_per_gas) + } + + fn priority_fee_or_price(&self) -> u128 { + self.max_priority_fee_per_gas + } + fn to(&self) -> TxKind { self.to } @@ -312,6 +324,18 @@ impl Transaction for TxEip7702 { fn input(&self) -> &[u8] { &self.input } + + fn ty(&self) -> u8 { + TxType::Eip7702 as u8 + } + + fn access_list(&self) -> Option<&AccessList> { + Some(&self.access_list) + } + + fn blob_versioned_hashes(&self) -> Option<&[B256]> { + None + } } impl SignableTransaction for TxEip7702 { diff --git a/crates/consensus/src/transaction/envelope.rs b/crates/consensus/src/transaction/envelope.rs index 50d12159ca9..5f028ab5431 100644 --- a/crates/consensus/src/transaction/envelope.rs +++ b/crates/consensus/src/transaction/envelope.rs @@ -1,7 +1,12 @@ +#[cfg(not(feature = "std"))] +use alloc::vec::Vec; use core::fmt; use crate::{Signed, Transaction, TxEip1559, TxEip2930, TxEip7702, TxLegacy}; -use alloy_eips::eip2718::{Decodable2718, Eip2718Error, Eip2718Result, Encodable2718}; +use alloy_eips::{ + eip2718::{Decodable2718, Eip2718Error, Eip2718Result, Encodable2718}, + eip2930::AccessList, +}; use alloy_primitives::{TxKind, B256}; use alloy_rlp::{Decodable, Encodable, Header}; @@ -433,6 +438,36 @@ impl Transaction for TxEnvelope { } } + fn max_fee_per_gas(&self) -> u128 { + match self { + Self::Legacy(tx) => tx.tx().max_fee_per_gas(), + Self::Eip2930(tx) => tx.tx().max_fee_per_gas(), + Self::Eip1559(tx) => tx.tx().max_fee_per_gas(), + Self::Eip4844(tx) => tx.tx().max_fee_per_gas(), + Self::Eip7702(tx) => tx.tx().max_fee_per_gas(), + } + } + + fn max_priority_fee_per_gas(&self) -> Option { + match self { + Self::Legacy(tx) => tx.tx().max_priority_fee_per_gas(), + Self::Eip2930(tx) => tx.tx().max_priority_fee_per_gas(), + Self::Eip1559(tx) => tx.tx().max_priority_fee_per_gas(), + Self::Eip4844(tx) => tx.tx().max_priority_fee_per_gas(), + Self::Eip7702(tx) => tx.tx().max_priority_fee_per_gas(), + } + } + + fn priority_fee_or_price(&self) -> u128 { + match self { + Self::Legacy(tx) => tx.tx().priority_fee_or_price(), + Self::Eip2930(tx) => tx.tx().priority_fee_or_price(), + Self::Eip1559(tx) => tx.tx().priority_fee_or_price(), + Self::Eip4844(tx) => tx.tx().priority_fee_or_price(), + Self::Eip7702(tx) => tx.tx().priority_fee_or_price(), + } + } + fn input(&self) -> &[u8] { match self { Self::Legacy(tx) => tx.tx().input(), @@ -472,6 +507,36 @@ impl Transaction for TxEnvelope { Self::Eip7702(tx) => tx.tx().value(), } } + + fn ty(&self) -> u8 { + match self { + Self::Legacy(tx) => tx.tx().ty(), + Self::Eip2930(tx) => tx.tx().ty(), + Self::Eip1559(tx) => tx.tx().ty(), + Self::Eip4844(tx) => tx.tx().ty(), + Self::Eip7702(tx) => tx.tx().ty(), + } + } + + fn access_list(&self) -> Option<&AccessList> { + match self { + Self::Legacy(tx) => tx.tx().access_list(), + Self::Eip2930(tx) => tx.tx().access_list(), + Self::Eip1559(tx) => tx.tx().access_list(), + Self::Eip4844(tx) => tx.tx().access_list(), + Self::Eip7702(tx) => tx.tx().access_list(), + } + } + + fn blob_versioned_hashes(&self) -> Option<&[B256]> { + match self { + Self::Legacy(tx) => tx.tx().blob_versioned_hashes(), + Self::Eip2930(tx) => tx.tx().blob_versioned_hashes(), + Self::Eip1559(tx) => tx.tx().blob_versioned_hashes(), + Self::Eip4844(tx) => tx.tx().blob_versioned_hashes(), + Self::Eip7702(tx) => tx.tx().blob_versioned_hashes(), + } + } } #[cfg(test)] diff --git a/crates/consensus/src/transaction/legacy.rs b/crates/consensus/src/transaction/legacy.rs index 04733e405cc..e45ac32ebd0 100644 --- a/crates/consensus/src/transaction/legacy.rs +++ b/crates/consensus/src/transaction/legacy.rs @@ -1,8 +1,11 @@ -use crate::{EncodableSignature, SignableTransaction, Signed, Transaction}; -use alloy_primitives::{keccak256, Bytes, ChainId, Signature, TxKind, U256}; -use alloy_rlp::{length_of_length, BufMut, Decodable, Encodable, Header, Result}; use core::mem; +use alloy_eips::eip2930::AccessList; +use alloy_primitives::{keccak256, Bytes, ChainId, Signature, TxKind, B256, U256}; +use alloy_rlp::{length_of_length, BufMut, Decodable, Encodable, Header, Result}; + +use crate::{EncodableSignature, SignableTransaction, Signed, Transaction, TxType}; + #[cfg(not(feature = "std"))] use alloc::vec::Vec; @@ -217,6 +220,18 @@ impl Transaction for TxLegacy { Some(self.gas_price) } + fn max_fee_per_gas(&self) -> u128 { + self.gas_price + } + + fn max_priority_fee_per_gas(&self) -> Option { + None + } + + fn priority_fee_or_price(&self) -> u128 { + self.gas_price + } + fn to(&self) -> TxKind { self.to } @@ -228,6 +243,18 @@ impl Transaction for TxLegacy { fn input(&self) -> &[u8] { &self.input } + + fn ty(&self) -> u8 { + TxType::Legacy as u8 + } + + fn access_list(&self) -> Option<&AccessList> { + None + } + + fn blob_versioned_hashes(&self) -> Option<&[B256]> { + None + } } impl SignableTransaction for TxLegacy { diff --git a/crates/consensus/src/transaction/mod.rs b/crates/consensus/src/transaction/mod.rs index 0b2307c4122..c77fa28da0d 100644 --- a/crates/consensus/src/transaction/mod.rs +++ b/crates/consensus/src/transaction/mod.rs @@ -1,6 +1,7 @@ //! Transaction types. use crate::Signed; +use alloy_eips::eip2930::AccessList; use alloy_primitives::{keccak256, ChainId, TxKind, B256, U256}; use core::any; @@ -51,6 +52,49 @@ pub trait Transaction: any::Any + Send + Sync + 'static { /// Get `gas_price`. fn gas_price(&self) -> Option; + /// Returns the EIP-1559 the maximum fee per gas the caller is willing to pay. + /// + /// For legacy transactions this is `gas_price`. + /// + /// This is also commonly referred to as the "Gas Fee Cap" (`GasFeeCap`). + fn max_fee_per_gas(&self) -> u128; + + /// Returns the EIP-1559 Priority fee the caller is paying to the block author. + /// + /// This will return `None` for non-EIP1559 transactions + fn max_priority_fee_per_gas(&self) -> Option; + + /// Return the max priority fee per gas if the transaction is an EIP-1559 transaction, and + /// otherwise return the gas price. + /// + /// # Warning + /// + /// This is different than the `max_priority_fee_per_gas` method, which returns `None` for + /// non-EIP-1559 transactions. + fn priority_fee_or_price(&self) -> u128; + + /// Returns the effective tip for this transaction. + /// + /// For EIP-1559 transactions: `min(max_fee_per_gas - base_fee, max_priority_fee_per_gas)`. + /// For legacy transactions: `gas_price - base_fee`. + fn effective_tip_per_gas(&self, base_fee: u64) -> Option { + let base_fee = base_fee as u128; + + let max_fee_per_gas = self.max_fee_per_gas(); + + // Check if max_fee_per_gas is less than base_fee + if max_fee_per_gas < base_fee { + return None; + } + + // Calculate the difference between max_fee_per_gas and base_fee + let fee = max_fee_per_gas - base_fee; + + // Compare the fee with max_priority_fee_per_gas (or gas price for non-EIP1559 transactions) + self.max_priority_fee_per_gas() + .map_or(Some(fee), |priority_fee| Some(fee.min(priority_fee))) + } + /// Get `to`. fn to(&self) -> TxKind; @@ -59,6 +103,17 @@ pub trait Transaction: any::Any + Send + Sync + 'static { /// Get `data`. fn input(&self) -> &[u8]; + + /// Returns the transaction type + fn ty(&self) -> u8; + + /// Returns the EIP2930 `access_list` for the particular transaction type. Returns `None` for + /// older transaction types. + fn access_list(&self) -> Option<&AccessList>; + + /// Blob versioned hashes for eip4844 transaction. For previous transaction types this is + /// `None`. + fn blob_versioned_hashes(&self) -> Option<&[B256]>; } /// A signable transaction. diff --git a/crates/consensus/src/transaction/typed.rs b/crates/consensus/src/transaction/typed.rs index 44062ea4a53..361b9049d31 100644 --- a/crates/consensus/src/transaction/typed.rs +++ b/crates/consensus/src/transaction/typed.rs @@ -1,8 +1,13 @@ +#[cfg(not(feature = "std"))] +use alloc::vec::Vec; + +use alloy_eips::eip2930::AccessList; +use alloy_primitives::{ChainId, TxKind, B256}; + use crate::{ transaction::eip4844::{TxEip4844, TxEip4844Variant, TxEip4844WithSidecar}, Transaction, TxEip1559, TxEip2930, TxEip7702, TxEnvelope, TxLegacy, TxType, }; -use alloy_primitives::{ChainId, TxKind}; /// The TypedTransaction enum represents all Ethereum transaction request types. /// @@ -174,6 +179,36 @@ impl Transaction for TypedTransaction { } } + fn max_fee_per_gas(&self) -> u128 { + match self { + Self::Legacy(tx) => tx.max_fee_per_gas(), + Self::Eip2930(tx) => tx.max_fee_per_gas(), + Self::Eip1559(tx) => tx.max_fee_per_gas(), + Self::Eip4844(tx) => tx.max_fee_per_gas(), + Self::Eip7702(tx) => tx.max_fee_per_gas(), + } + } + + fn max_priority_fee_per_gas(&self) -> Option { + match self { + Self::Legacy(tx) => tx.max_priority_fee_per_gas(), + Self::Eip2930(tx) => tx.max_priority_fee_per_gas(), + Self::Eip1559(tx) => tx.max_priority_fee_per_gas(), + Self::Eip4844(tx) => tx.max_priority_fee_per_gas(), + Self::Eip7702(tx) => tx.max_priority_fee_per_gas(), + } + } + + fn priority_fee_or_price(&self) -> u128 { + match self { + Self::Legacy(tx) => tx.priority_fee_or_price(), + Self::Eip2930(tx) => tx.priority_fee_or_price(), + Self::Eip1559(tx) => tx.priority_fee_or_price(), + Self::Eip4844(tx) => tx.priority_fee_or_price(), + Self::Eip7702(tx) => tx.priority_fee_or_price(), + } + } + fn to(&self) -> TxKind { match self { Self::Legacy(tx) => tx.to(), @@ -203,6 +238,36 @@ impl Transaction for TypedTransaction { Self::Eip7702(tx) => tx.input(), } } + + fn ty(&self) -> u8 { + match self { + Self::Legacy(tx) => tx.ty(), + Self::Eip2930(tx) => tx.ty(), + Self::Eip1559(tx) => tx.ty(), + Self::Eip4844(tx) => tx.ty(), + Self::Eip7702(tx) => tx.ty(), + } + } + + fn access_list(&self) -> Option<&AccessList> { + match self { + Self::Legacy(tx) => tx.access_list(), + Self::Eip2930(tx) => tx.access_list(), + Self::Eip1559(tx) => tx.access_list(), + Self::Eip4844(tx) => tx.access_list(), + Self::Eip7702(tx) => tx.access_list(), + } + } + + fn blob_versioned_hashes(&self) -> Option<&[B256]> { + match self { + Self::Legacy(tx) => tx.blob_versioned_hashes(), + Self::Eip2930(tx) => tx.blob_versioned_hashes(), + Self::Eip1559(tx) => tx.blob_versioned_hashes(), + Self::Eip4844(tx) => tx.blob_versioned_hashes(), + Self::Eip7702(tx) => tx.blob_versioned_hashes(), + } + } } #[cfg(feature = "serde")] From 0de6aa8b2a13901154e7f94e2c9ad86018252373 Mon Sep 17 00:00:00 2001 From: Alexey Shekhirin Date: Fri, 23 Aug 2024 06:19:30 +0100 Subject: [PATCH 090/186] feat(rpc-types): `debug_executionWitness` (#1178) * feat(rpc-types): `debug_executionWitness` * remove unused deps * fix preimage field doc * clarify unhashed --- Cargo.toml | 1 + README.md | 1 + crates/rpc-types-debug/CHANGELOG.md | 6 ++++++ crates/rpc-types-debug/Cargo.toml | 24 ++++++++++++++++++++++++ crates/rpc-types-debug/README.md | 3 +++ crates/rpc-types-debug/src/debug.rs | 17 +++++++++++++++++ crates/rpc-types-debug/src/lib.rs | 10 ++++++++++ crates/rpc-types/Cargo.toml | 2 ++ crates/rpc-types/src/lib.rs | 3 +++ 9 files changed, 67 insertions(+) create mode 100644 crates/rpc-types-debug/CHANGELOG.md create mode 100644 crates/rpc-types-debug/Cargo.toml create mode 100644 crates/rpc-types-debug/README.md create mode 100644 crates/rpc-types-debug/src/debug.rs create mode 100644 crates/rpc-types-debug/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 9067354f941..f9fcb71e0ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,6 +50,7 @@ alloy-rpc-client = { version = "0.2", path = "crates/rpc-client", default-featur alloy-rpc-types-admin = { version = "0.2", path = "crates/rpc-types-admin", default-features = false } alloy-rpc-types-anvil = { version = "0.2", path = "crates/rpc-types-anvil", default-features = false } alloy-rpc-types-beacon = { version = "0.2", path = "crates/rpc-types-beacon", default-features = false } +alloy-rpc-types-debug = { version = "0.2", path = "crates/rpc-types-debug", default-features = false } alloy-rpc-types-engine = { version = "0.2", path = "crates/rpc-types-engine", default-features = false } alloy-rpc-types-eth = { version = "0.2", path = "crates/rpc-types-eth", default-features = false } alloy-rpc-types-mev = { version = "0.2", path = "crates/rpc-types-mev", default-features = false } diff --git a/README.md b/README.md index 1f710d763ba..e528389819e 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,7 @@ This repository contains the following crates: - [`alloy-rpc-types-admin`] - Types for the `admin` Ethereum JSON-RPC namespace - [`alloy-rpc-types-anvil`] - Types for the [Anvil] development node's Ethereum JSON-RPC namespace - [`alloy-rpc-types-beacon`] - Types for the [Ethereum Beacon Node API][beacon-apis] + - [`alloy-rpc-types-debug`] - Types for the `debug` Ethereum JSON-RPC namespace - [`alloy-rpc-types-engine`] - Types for the `engine` Ethereum JSON-RPC namespace - [`alloy-rpc-types-eth`] - Types for the `eth` Ethereum JSON-RPC namespace - [`alloy-rpc-types-mev`] - Types for the MEV bundle JSON-RPC namespace diff --git a/crates/rpc-types-debug/CHANGELOG.md b/crates/rpc-types-debug/CHANGELOG.md new file mode 100644 index 00000000000..9e0e2bb287b --- /dev/null +++ b/crates/rpc-types-debug/CHANGELOG.md @@ -0,0 +1,6 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). diff --git a/crates/rpc-types-debug/Cargo.toml b/crates/rpc-types-debug/Cargo.toml new file mode 100644 index 00000000000..d8e80c2898a --- /dev/null +++ b/crates/rpc-types-debug/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "alloy-rpc-types-debug" +description = "Ethereum RPC debug types" + +version.workspace = true +edition.workspace = true +rust-version.workspace = true +authors.workspace = true +license.workspace = true +homepage.workspace = true +repository.workspace = true +exclude.workspace = true + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] + +[lints] +workspace = true + +[dependencies] +alloy-primitives = { workspace = true, features = ["serde", "std"] } + +serde.workspace = true diff --git a/crates/rpc-types-debug/README.md b/crates/rpc-types-debug/README.md new file mode 100644 index 00000000000..1fa9386d84d --- /dev/null +++ b/crates/rpc-types-debug/README.md @@ -0,0 +1,3 @@ +# alloy-rpc-types-debug + +Types for the `debug` Ethereum JSON-RPC namespace. diff --git a/crates/rpc-types-debug/src/debug.rs b/crates/rpc-types-debug/src/debug.rs new file mode 100644 index 00000000000..f1cbf76f44b --- /dev/null +++ b/crates/rpc-types-debug/src/debug.rs @@ -0,0 +1,17 @@ +//! Types for the `debug` API. + +use alloy_primitives::{Bytes, B256}; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +/// Represents the execution witness of a block. Contains an optional map of state preimages. +#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] +pub struct ExecutionWitness { + /// Map of all hashed trie nodes to their preimages that were required during the execution of + /// the block, including during state root recomputation. + pub witness: HashMap, + /// Map of all hashed account addresses and storage slots to their preimages (unhashed account + /// addresses and storage slots, respectively) that were required during the execution of the + /// block. during the execution of the block. + pub state_preimages: Option>, +} diff --git a/crates/rpc-types-debug/src/lib.rs b/crates/rpc-types-debug/src/lib.rs new file mode 100644 index 00000000000..5b142713629 --- /dev/null +++ b/crates/rpc-types-debug/src/lib.rs @@ -0,0 +1,10 @@ +#![doc = include_str!("../README.md")] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/alloy-rs/core/main/assets/alloy.jpg", + html_favicon_url = "https://raw.githubusercontent.com/alloy-rs/core/main/assets/favicon.ico" +)] +#![cfg_attr(not(test), warn(unused_crate_dependencies))] +#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] + +mod debug; +pub use debug::*; diff --git a/crates/rpc-types/Cargo.toml b/crates/rpc-types/Cargo.toml index a3163299856..0b50e49609b 100644 --- a/crates/rpc-types/Cargo.toml +++ b/crates/rpc-types/Cargo.toml @@ -23,6 +23,7 @@ alloy-serde.workspace = true alloy-rpc-types-admin = { workspace = true, optional = true } alloy-rpc-types-anvil = { workspace = true, optional = true } alloy-rpc-types-beacon = { workspace = true, optional = true } +alloy-rpc-types-debug = { workspace = true, optional = true } alloy-rpc-types-engine = { workspace = true, optional = true } alloy-rpc-types-eth = { workspace = true, optional = true } alloy-rpc-types-mev = { workspace = true, optional = true } @@ -38,6 +39,7 @@ default = ["eth", "alloy-rpc-types-engine?/default"] admin = ["dep:alloy-rpc-types-admin"] anvil = ["dep:alloy-rpc-types-anvil"] beacon = ["dep:alloy-rpc-types-beacon"] +debug = ["dep:alloy-rpc-types-debug"] engine = ["dep:alloy-rpc-types-engine"] eth = ["dep:alloy-rpc-types-eth"] mev = ["dep:alloy-rpc-types-mev"] diff --git a/crates/rpc-types/src/lib.rs b/crates/rpc-types/src/lib.rs index b158ec7df41..2a6b8d04b74 100644 --- a/crates/rpc-types/src/lib.rs +++ b/crates/rpc-types/src/lib.rs @@ -20,6 +20,9 @@ pub use alloy_rpc_types_anvil as anvil; #[cfg(feature = "beacon")] pub use alloy_rpc_types_beacon as beacon; +#[cfg(feature = "debug")] +pub use alloy_rpc_types_debug as debug; + #[cfg(feature = "engine")] pub use alloy_rpc_types_engine as engine; From dbd9d7712da879ab1736a89caa37c2135fa9fafa Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Fri, 23 Aug 2024 07:43:38 +0200 Subject: [PATCH 091/186] test: flaky rpc (#1180) --- crates/node-bindings/src/anvil.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/node-bindings/src/anvil.rs b/crates/node-bindings/src/anvil.rs index a20cdaaf12a..21028610210 100644 --- a/crates/node-bindings/src/anvil.rs +++ b/crates/node-bindings/src/anvil.rs @@ -408,7 +408,7 @@ mod tests { #[test] fn assert_chain_id() { - let anvil = Anvil::new().fork("https://rpc.ankr.com/eth").spawn(); + let anvil = Anvil::new().fork("https://eth.llamarpc.com ").spawn(); assert_eq!(anvil.chain_id(), 1); } From 974684bc76b36f17a2490c56ad9e7dbbcf825972 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Fri, 23 Aug 2024 21:56:00 +0800 Subject: [PATCH 092/186] fix: use `server_id` when unsubscribing (#1182) fix: use server_id when unsubscribing --- crates/provider/src/provider/root.rs | 4 ++-- crates/provider/src/provider/trait.rs | 2 +- crates/pubsub/src/frontend.rs | 6 +++--- crates/pubsub/src/ix.rs | 6 +++--- crates/pubsub/src/managers/sub.rs | 5 +++++ crates/pubsub/src/service.rs | 18 ++++++++++-------- crates/rpc-client/src/client.rs | 4 ++-- 7 files changed, 26 insertions(+), 19 deletions(-) diff --git a/crates/provider/src/provider/root.rs b/crates/provider/src/provider/root.rs index 1b3f524cc5e..a47c8f28824 100644 --- a/crates/provider/src/provider/root.rs +++ b/crates/provider/src/provider/root.rs @@ -87,14 +87,14 @@ impl RootProvider { #[cfg(feature = "pubsub")] pub async fn get_subscription( &self, - id: alloy_primitives::U256, + id: alloy_primitives::B256, ) -> alloy_transport::TransportResult> { self.pubsub_frontend()?.get_subscription(id).await.map(Subscription::from) } /// Unsubscribes from the subscription corresponding to the given RPC subscription ID. #[cfg(feature = "pubsub")] - pub fn unsubscribe(&self, id: alloy_primitives::U256) -> alloy_transport::TransportResult<()> { + pub fn unsubscribe(&self, id: alloy_primitives::B256) -> alloy_transport::TransportResult<()> { self.pubsub_frontend()?.unsubscribe(id) } diff --git a/crates/provider/src/provider/trait.rs b/crates/provider/src/provider/trait.rs index 00d61a1b5ca..039cd9268aa 100644 --- a/crates/provider/src/provider/trait.rs +++ b/crates/provider/src/provider/trait.rs @@ -864,7 +864,7 @@ pub trait Provider: /// Cancels a subscription given the subscription ID. #[cfg(feature = "pubsub")] - async fn unsubscribe(&self, id: U256) -> TransportResult<()> { + async fn unsubscribe(&self, id: B256) -> TransportResult<()> { self.root().unsubscribe(id) } diff --git a/crates/pubsub/src/frontend.rs b/crates/pubsub/src/frontend.rs index e568dae2a5d..9f6ebbdfd83 100644 --- a/crates/pubsub/src/frontend.rs +++ b/crates/pubsub/src/frontend.rs @@ -1,6 +1,6 @@ use crate::{ix::PubSubInstruction, managers::InFlight, RawSubscription}; use alloy_json_rpc::{RequestPacket, Response, ResponsePacket, SerializedRequest}; -use alloy_primitives::U256; +use alloy_primitives::B256; use alloy_transport::{TransportError, TransportErrorKind, TransportFut, TransportResult}; use futures::{future::try_join_all, FutureExt, TryFutureExt}; use std::{ @@ -38,7 +38,7 @@ impl PubSubFrontend { /// Get the subscription ID for a local ID. pub fn get_subscription( &self, - id: U256, + id: B256, ) -> impl Future> + Send + 'static { let backend_tx = self.tx.clone(); async move { @@ -51,7 +51,7 @@ impl PubSubFrontend { } /// Unsubscribe from a subscription. - pub fn unsubscribe(&self, id: U256) -> TransportResult<()> { + pub fn unsubscribe(&self, id: B256) -> TransportResult<()> { self.tx .send(PubSubInstruction::Unsubscribe(id)) .map_err(|_| TransportErrorKind::backend_gone()) diff --git a/crates/pubsub/src/ix.rs b/crates/pubsub/src/ix.rs index ee78d7ac713..6698a4e6a16 100644 --- a/crates/pubsub/src/ix.rs +++ b/crates/pubsub/src/ix.rs @@ -1,5 +1,5 @@ use crate::{managers::InFlight, RawSubscription}; -use alloy_primitives::U256; +use alloy_primitives::B256; use std::fmt; use tokio::sync::oneshot; @@ -8,9 +8,9 @@ pub(crate) enum PubSubInstruction { /// Send a request. Request(InFlight), /// Get the subscription ID for a local ID. - GetSub(U256, oneshot::Sender), + GetSub(B256, oneshot::Sender), /// Unsubscribe from a subscription. - Unsubscribe(U256), + Unsubscribe(B256), } impl fmt::Debug for PubSubInstruction { diff --git a/crates/pubsub/src/managers/sub.rs b/crates/pubsub/src/managers/sub.rs index 6081541d83d..617bc8905b8 100644 --- a/crates/pubsub/src/managers/sub.rs +++ b/crates/pubsub/src/managers/sub.rs @@ -63,6 +63,11 @@ impl SubscriptionManager { self.local_to_server.get_by_right(server_id).copied() } + /// De-alias an alias, getting the original ID. + pub(crate) fn server_id_for(&self, local_id: &B256) -> Option<&SubId> { + self.local_to_server.get_by_left(local_id) + } + /// Drop all server_ids. pub(crate) fn drop_server_ids(&mut self) { self.local_to_server.clear(); diff --git a/crates/pubsub/src/service.rs b/crates/pubsub/src/service.rs index afd503e4e40..32d4e619c84 100644 --- a/crates/pubsub/src/service.rs +++ b/crates/pubsub/src/service.rs @@ -5,7 +5,7 @@ use crate::{ PubSubConnect, PubSubFrontend, RawSubscription, }; use alloy_json_rpc::{Id, PubSubItem, Request, Response, ResponsePayload, SubId}; -use alloy_primitives::U256; +use alloy_primitives::B256; use alloy_transport::{ utils::{to_json_raw_value, Spawnable}, TransportErrorKind, TransportResult, @@ -123,19 +123,21 @@ impl PubSubService { /// the subscription does not exist, the waiter is sent nothing, and the /// `tx` is dropped. This notifies the waiter that the subscription does /// not exist. - fn service_get_sub(&mut self, local_id: U256, tx: oneshot::Sender) { - if let Some(rx) = self.subs.get_subscription(local_id.into()) { + fn service_get_sub(&mut self, local_id: B256, tx: oneshot::Sender) { + if let Some(rx) = self.subs.get_subscription(local_id) { let _ = tx.send(rx); } } /// Service an unsubscribe instruction. - fn service_unsubscribe(&mut self, local_id: U256) -> TransportResult<()> { - let req = Request::new("eth_unsubscribe", Id::None, [local_id]); - let brv = req.serialize().expect("no ser error").take_request(); + fn service_unsubscribe(&mut self, local_id: B256) -> TransportResult<()> { + if let Some(server_id) = self.subs.server_id_for(&local_id) { + let req = Request::new("eth_unsubscribe", Id::None, [server_id]); + let brv = req.serialize().expect("no ser error").take_request(); - self.dispatch_request(brv)?; - self.subs.remove_sub(local_id.into()); + self.dispatch_request(brv)?; + } + self.subs.remove_sub(local_id); Ok(()) } diff --git a/crates/rpc-client/src/client.rs b/crates/rpc-client/src/client.rs index e52ca93278a..a32e08950b2 100644 --- a/crates/rpc-client/src/client.rs +++ b/crates/rpc-client/src/client.rs @@ -306,14 +306,14 @@ mod pubsub_impl { impl RpcClientInner { /// Get a [`RawSubscription`] for the given subscription ID. - pub async fn get_raw_subscription(&self, id: alloy_primitives::U256) -> RawSubscription { + pub async fn get_raw_subscription(&self, id: alloy_primitives::B256) -> RawSubscription { self.transport.get_subscription(id).await.unwrap() } /// Get a [`Subscription`] for the given subscription ID. pub async fn get_subscription( &self, - id: alloy_primitives::U256, + id: alloy_primitives::B256, ) -> Subscription { Subscription::from(self.get_raw_subscription(id).await) } From 8a06509c3f85885ecfab110af0819b354d794b68 Mon Sep 17 00:00:00 2001 From: Miguel Tavares Date: Fri, 23 Aug 2024 13:50:50 -0300 Subject: [PATCH 093/186] feat: make block struct generic over header type (#1179) * make block struct generic over header type * add generic default, make some changes * change generic name and self --- crates/network/src/any/mod.rs | 2 +- crates/rpc-types-eth/src/block.rs | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/network/src/any/mod.rs b/crates/network/src/any/mod.rs index 6e1b2cab832..e0048d25cb3 100644 --- a/crates/network/src/any/mod.rs +++ b/crates/network/src/any/mod.rs @@ -75,5 +75,5 @@ impl Network for AnyNetwork { type HeaderResponse = Header; - type BlockResponse = WithOtherFields>; + type BlockResponse = WithOtherFields>; } diff --git a/crates/rpc-types-eth/src/block.rs b/crates/rpc-types-eth/src/block.rs index 2660f138a3f..0d6661ee5a8 100644 --- a/crates/rpc-types-eth/src/block.rs +++ b/crates/rpc-types-eth/src/block.rs @@ -14,10 +14,10 @@ pub use alloy_eips::{ /// Block representation #[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct Block { +pub struct Block { /// Header of the block. #[serde(flatten)] - pub header: Header, + pub header: H, /// Uncles' hashes. #[serde(default)] pub uncles: Vec, @@ -36,7 +36,7 @@ pub struct Block { pub withdrawals: Option>, } -impl Block { +impl Block { /// Converts a block with Tx hashes into a full block. pub fn into_full_block(self, txs: Vec) -> Self { Self { transactions: txs.into(), ..self } @@ -334,9 +334,9 @@ pub struct BlockOverrides { pub block_hash: Option>, } -impl BlockResponse for Block { +impl BlockResponse for Block { type Transaction = T; - type Header = Header; + type Header = H; fn header(&self) -> &Self::Header { &self.header From ab462f12ac40fd16bd9882c9451d7d62f7c31d37 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Sat, 24 Aug 2024 09:35:39 +0200 Subject: [PATCH 094/186] fix: add missing op fields (#1187) --- .../rpc-types-eth/src/transaction/optimism.rs | 52 ++++++++++++++++--- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/crates/rpc-types-eth/src/transaction/optimism.rs b/crates/rpc-types-eth/src/transaction/optimism.rs index 835806ce414..86a1bfbb3ad 100644 --- a/crates/rpc-types-eth/src/transaction/optimism.rs +++ b/crates/rpc-types-eth/src/transaction/optimism.rs @@ -26,7 +26,7 @@ pub struct OptimismTransactionFields { pub is_system_tx: Option, } -/// Additional fields for Optimism transaction receipts +/// Additional fields for Optimism transaction receipts: #[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] #[doc(alias = "OptimismTxReceiptFields")] @@ -37,18 +37,27 @@ pub struct OptimismTransactionReceiptFields { /// Deposit receipt version for deposit transactions post-canyon #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] pub deposit_receipt_version: Option, - /// L1 fee for the transaction + /// Present from pre-bedrock. L1 Basefee after Bedrock + #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] + pub l1_gas_price: Option, + /// Always null prior to the Ecotone hardfork. + #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] + pub l1_blob_base_fee: Option, + /// Present from pre-bedrock, deprecated as of Fjord. + #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] + pub l1_gas_used: Option, + /// Present from pre-bedrock. L1 fee for the transaction #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] pub l1_fee: Option, - /// L1 fee scalar for the transaction + /// Present from pre-bedrock to Ecotone. Nil after Ecotone #[serde(default, skip_serializing_if = "Option::is_none", with = "l1_fee_scalar_serde")] pub l1_fee_scalar: Option, - /// L1 gas price for the transaction + /// Always null prior to the Ecotone hardfork. #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] - pub l1_gas_price: Option, - /// L1 gas used for the transaction + pub l1_base_fee_scalar: Option, + /// Always null prior to the Ecotone hardfork #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] - pub l1_gas_used: Option, + pub l1_blob_base_fee_scalar: Option, } impl From for OtherFields { @@ -136,4 +145,33 @@ mod tests { let op_fields: OptimismTransactionReceiptFields = serde_json::from_value(json).unwrap(); assert_eq!(op_fields.l1_fee_scalar, None); } + + #[test] + fn deserialize_op_receipt() { + let s = r#"{ + "blockHash": "0x70a8a64a0f8b141718f60e49c30f027cb9e4f91753d5f13a48d8e1ad263c08bf", + "blockNumber": "0x1185e55", + "contractAddress": null, + "cumulativeGasUsed": "0xc74f5e", + "effectiveGasPrice": "0x31b41b", + "from": "0x889ebdac39408782b5165c5185c1a769b4dd3ce6", + "gasUsed": "0x5208", + "l1BaseFeeScalar": "0x8dd", + "l1BlobBaseFee": "0x1", + "l1BlobBaseFeeScalar": "0x101c12", + "l1Fee": "0x125f723f3", + "l1GasPrice": "0x50f928b4", + "l1GasUsed": "0x640", + "logs": [ + ], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "0x1", + "to": "0x7449061f45d7b39b3b80b4159286cd8682f60a3c", + "transactionHash": "0xca564948e3e825f65731424da063240eec34ba921dd117ac5d06b8c2e0b2d962", + "transactionIndex": "0x3e", + "type": "0x2" +} +"#; + let _receipt = serde_json::from_str::(s).unwrap(); + } } From 2451ff0e95b55a71826f16dc6c64b278b0e1cf15 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Sat, 24 Aug 2024 10:03:43 +0200 Subject: [PATCH 095/186] chore: add deposit receipt version (#1188) --- crates/rpc-types-eth/src/transaction/optimism.rs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/crates/rpc-types-eth/src/transaction/optimism.rs b/crates/rpc-types-eth/src/transaction/optimism.rs index 86a1bfbb3ad..5eff353a183 100644 --- a/crates/rpc-types-eth/src/transaction/optimism.rs +++ b/crates/rpc-types-eth/src/transaction/optimism.rs @@ -4,12 +4,12 @@ use alloy_primitives::B256; use alloy_serde::OtherFields; use serde::{Deserialize, Serialize}; -/// Optimism specific transaction fields +/// Optimism specific transaction fields: #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] #[doc(alias = "OptimismTxFields")] pub struct OptimismTransactionFields { /// Hash that uniquely identifies the source of the deposit. - #[serde(rename = "sourceHash", skip_serializing_if = "Option::is_none")] + #[serde(default, rename = "sourceHash", skip_serializing_if = "Option::is_none")] pub source_hash: Option, /// The ETH value to mint on L2 #[serde( @@ -21,9 +21,17 @@ pub struct OptimismTransactionFields { pub mint: Option, /// Field indicating whether the transaction is a system transaction, and therefore /// exempt from the L2 gas limit. - #[serde(rename = "isSystemTx", skip_serializing_if = "Option::is_none")] + #[serde(default, rename = "isSystemTx", skip_serializing_if = "Option::is_none")] #[doc(alias = "is_system_transaction")] pub is_system_tx: Option, + /// Deposit receipt version for Optimism deposit transactions, post-Canyon only + /// + /// + /// The deposit receipt version was introduced in Canyon to indicate an update to how + /// receipt hashes should be computed when set. The state transition process + /// ensures this is only set for post-Canyon deposit transactions. + #[serde(default, rename = "depositReceiptVersion", skip_serializing_if = "Option::is_none")] + pub deposit_receipt_version: Option, } /// Additional fields for Optimism transaction receipts: From ca1ef6b3e662fefe2f45b6028991afacd920d24f Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Sat, 24 Aug 2024 16:16:18 +0200 Subject: [PATCH 096/186] Add emhane to codeowners (#1189) --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 14f5ed1107a..a9cb881442e 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -* @danipopes @gakonst @mattsse @onbjerg @prestwich @evalir +* @danipopes @gakonst @mattsse @onbjerg @prestwich @evalir @emhane From 2033626c6d7fdbf29f6d741e8280f0218f12ea64 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Mon, 26 Aug 2024 17:32:04 +0800 Subject: [PATCH 097/186] fix: change generics order for `Block` (#1192) * fix: change generics order for Block * fix * fix --- crates/network/src/any/mod.rs | 2 +- crates/rpc-types-eth/src/block.rs | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/crates/network/src/any/mod.rs b/crates/network/src/any/mod.rs index e0048d25cb3..a058db712cd 100644 --- a/crates/network/src/any/mod.rs +++ b/crates/network/src/any/mod.rs @@ -75,5 +75,5 @@ impl Network for AnyNetwork { type HeaderResponse = Header; - type BlockResponse = WithOtherFields>; + type BlockResponse = WithOtherFields>; } diff --git a/crates/rpc-types-eth/src/block.rs b/crates/rpc-types-eth/src/block.rs index 0d6661ee5a8..70833d34371 100644 --- a/crates/rpc-types-eth/src/block.rs +++ b/crates/rpc-types-eth/src/block.rs @@ -1,7 +1,9 @@ //! Block RPC types. use crate::{ConversionError, Transaction, Withdrawal}; -use alloy_network_primitives::{BlockResponse, BlockTransactions, HeaderResponse}; +use alloy_network_primitives::{ + BlockResponse, BlockTransactions, HeaderResponse, TransactionResponse, +}; use alloy_primitives::{Address, BlockHash, Bloom, Bytes, B256, B64, U256}; use serde::{ser::Error, Deserialize, Serialize, Serializer}; use std::{collections::BTreeMap, ops::Deref}; @@ -14,7 +16,7 @@ pub use alloy_eips::{ /// Block representation #[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct Block { +pub struct Block { /// Header of the block. #[serde(flatten)] pub header: H, @@ -36,9 +38,9 @@ pub struct Block { pub withdrawals: Option>, } -impl Block { +impl Block { /// Converts a block with Tx hashes into a full block. - pub fn into_full_block(self, txs: Vec) -> Self { + pub fn into_full_block(self, txs: Vec) -> Self { Self { transactions: txs.into(), ..self } } } @@ -334,7 +336,7 @@ pub struct BlockOverrides { pub block_hash: Option>, } -impl BlockResponse for Block { +impl BlockResponse for Block { type Transaction = T; type Header = H; From e2cc14f78c43f251ba7008292076cc6948dcdea6 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Mon, 26 Aug 2024 17:32:15 +0800 Subject: [PATCH 098/186] feat: add block and transaction generics to otterscan and txpool types (#1183) * feat: add transaction generic to ots types * txpool generics --- crates/provider/src/ext/txpool.rs | 16 ++++++++----- crates/rpc-types-trace/src/otterscan.rs | 30 ++++++++++++++----------- crates/rpc-types-txpool/src/txpool.rs | 16 ++++++------- 3 files changed, 36 insertions(+), 26 deletions(-) diff --git a/crates/provider/src/ext/txpool.rs b/crates/provider/src/ext/txpool.rs index 9086926356c..83b1d64f73e 100644 --- a/crates/provider/src/ext/txpool.rs +++ b/crates/provider/src/ext/txpool.rs @@ -9,19 +9,22 @@ use alloy_transport::{Transport, TransportResult}; #[allow(unused, unreachable_pub)] #[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)] -pub trait TxPoolApi: Send + Sync { +pub trait TxPoolApi: Send + Sync { /// Returns the content of the transaction pool. /// /// Lists the exact details of all the transactions currently pending for inclusion in the next /// block(s), as well as the ones that are being scheduled for future execution only. /// /// See [here](https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_content) for more details - async fn txpool_content(&self) -> TransportResult; + async fn txpool_content(&self) -> TransportResult>; /// Returns the content of the transaction pool filtered by a specific address. /// /// See [here](https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_contentFrom) for more details - async fn txpool_content_from(&self, from: Address) -> TransportResult; + async fn txpool_content_from( + &self, + from: Address, + ) -> TransportResult>; /// Returns a textual summary of each transaction in the pool. /// @@ -50,11 +53,14 @@ where T: Transport + Clone, N: Network, { - async fn txpool_content(&self) -> TransportResult { + async fn txpool_content(&self) -> TransportResult> { self.client().request("txpool_content", ()).await } - async fn txpool_content_from(&self, from: Address) -> TransportResult { + async fn txpool_content_from( + &self, + from: Address, + ) -> TransportResult> { self.client().request("txpool_contentFrom", (from,)).await } diff --git a/crates/rpc-types-trace/src/otterscan.rs b/crates/rpc-types-trace/src/otterscan.rs index a56ed47366e..7d428a64913 100644 --- a/crates/rpc-types-trace/src/otterscan.rs +++ b/crates/rpc-types-trace/src/otterscan.rs @@ -102,17 +102,17 @@ pub struct InternalIssuance { /// Custom `Block` struct that includes transaction count for Otterscan responses #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct OtsBlock { +pub struct OtsBlock { /// The block information. #[serde(flatten)] - pub block: Block, + pub block: Block, /// The number of transactions in the block. #[doc(alias = "tx_count")] pub transaction_count: usize, } -impl From for OtsBlock { - fn from(block: Block) -> Self { +impl From> for OtsBlock { + fn from(block: Block) -> Self { Self { transaction_count: block.transactions.len(), block } } } @@ -138,8 +138,8 @@ pub struct OtsSlimBlock { pub transaction_count: usize, } -impl From for OtsSlimBlock { - fn from(block: Block) -> Self { +impl From> for OtsSlimBlock { + fn from(block: Block) -> Self { Self { header: block.header, uncles: block.uncles, @@ -162,8 +162,8 @@ pub struct BlockDetails { pub total_fees: U256, } -impl From> for BlockDetails { - fn from(rich_block: Rich) -> Self { +impl From>> for BlockDetails { + fn from(rich_block: Rich>) -> Self { Self { block: rich_block.inner.into(), issuance: Default::default(), @@ -174,7 +174,11 @@ impl From> for BlockDetails { impl BlockDetails { /// Create a new `BlockDetails` struct. - pub fn new(rich_block: Rich, issuance: InternalIssuance, total_fees: U256) -> Self { + pub fn new( + rich_block: Rich>, + issuance: InternalIssuance, + total_fees: U256, + ) -> Self { Self { block: rich_block.inner.into(), issuance, total_fees } } } @@ -220,9 +224,9 @@ pub struct OtsReceipt { /// Custom struct for otterscan `getBlockTransactions` RPC response #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -pub struct OtsBlockTransactions { +pub struct OtsBlockTransactions { /// The full block information with transaction count. - pub fullblock: OtsBlock, + pub fullblock: OtsBlock, /// The list of transaction receipts. pub receipts: Vec, } @@ -232,10 +236,10 @@ pub struct OtsBlockTransactions { #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] #[doc(alias = "TxWithReceipts")] -pub struct TransactionsWithReceipts { +pub struct TransactionsWithReceipts { /// The list of transactions. #[doc(alias = "transactions")] - pub txs: Vec, + pub txs: Vec, /// The list of transaction receipts. pub receipts: Vec, /// Indicates if this is the first page of results. diff --git a/crates/rpc-types-txpool/src/txpool.rs b/crates/rpc-types-txpool/src/txpool.rs index ea244e455b3..f698708427e 100644 --- a/crates/rpc-types-txpool/src/txpool.rs +++ b/crates/rpc-types-txpool/src/txpool.rs @@ -111,16 +111,16 @@ impl Serialize for TxpoolInspectSummary { /// /// See [here](https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_content) for more details #[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] -pub struct TxpoolContent { +pub struct TxpoolContent { /// pending tx - pub pending: BTreeMap>, + pub pending: BTreeMap>, /// queued tx - pub queued: BTreeMap>, + pub queued: BTreeMap>, } -impl TxpoolContent { +impl TxpoolContent { /// Removes the transactions from the given sender - pub fn remove_from(&mut self, sender: &Address) -> TxpoolContentFrom { + pub fn remove_from(&mut self, sender: &Address) -> TxpoolContentFrom { TxpoolContentFrom { pending: self.pending.remove(sender).unwrap_or_default(), queued: self.queued.remove(sender).unwrap_or_default(), @@ -134,11 +134,11 @@ impl TxpoolContent { /// /// See [here](https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_contentFrom) for more details #[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] -pub struct TxpoolContentFrom { +pub struct TxpoolContentFrom { /// pending tx - pub pending: BTreeMap, + pub pending: BTreeMap, /// queued tx - pub queued: BTreeMap, + pub queued: BTreeMap, } /// Transaction Pool Inspect From ff4e72e8a6e32a1fb158d5cf5a3eb0621527e844 Mon Sep 17 00:00:00 2001 From: Miguel Tavares Date: Mon, 26 Aug 2024 07:14:12 -0300 Subject: [PATCH 099/186] chore: remove RichBlock and RichHeader types (#1185) remove RichBlock and RichHeader types --- crates/rpc-types-eth/src/block.rs | 19 +++++++------------ crates/rpc-types-eth/src/pubsub.rs | 5 +++-- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/crates/rpc-types-eth/src/block.rs b/crates/rpc-types-eth/src/block.rs index 70833d34371..c419b9c8ed0 100644 --- a/crates/rpc-types-eth/src/block.rs +++ b/crates/rpc-types-eth/src/block.rs @@ -5,6 +5,7 @@ use alloy_network_primitives::{ BlockResponse, BlockTransactions, HeaderResponse, TransactionResponse, }; use alloy_primitives::{Address, BlockHash, Bloom, Bytes, B256, B64, U256}; +use alloy_serde::WithOtherFields; use serde::{ser::Error, Deserialize, Serialize, Serializer}; use std::{collections::BTreeMap, ops::Deref}; @@ -236,21 +237,15 @@ pub enum BlockError { RlpDecodeRawBlock(alloy_rlp::Error), } -/// A Block representation that allows to include additional fields -pub type RichBlock = Rich; - -impl From for RichBlock { +impl From for WithOtherFields { fn from(inner: Block) -> Self { - Self { inner, extra_info: Default::default() } + Self { inner, other: Default::default() } } } -/// Header representation with additional info. -pub type RichHeader = Rich
; - -impl From
for RichHeader { +impl From
for WithOtherFields
{ fn from(inner: Header) -> Self { - Self { inner, extra_info: Default::default() } + Self { inner, other: Default::default() } } } @@ -538,9 +533,9 @@ mod tests { "size": "0xaeb6" }"#; - let block = serde_json::from_str::(s).unwrap(); + let block = serde_json::from_str::>(s).unwrap(); let serialized = serde_json::to_string(&block).unwrap(); - let block2 = serde_json::from_str::(&serialized).unwrap(); + let block2 = serde_json::from_str::>(&serialized).unwrap(); assert_eq!(block, block2); } diff --git a/crates/rpc-types-eth/src/pubsub.rs b/crates/rpc-types-eth/src/pubsub.rs index d4417954a2d..b5e2dc512e7 100644 --- a/crates/rpc-types-eth/src/pubsub.rs +++ b/crates/rpc-types-eth/src/pubsub.rs @@ -1,7 +1,8 @@ //! Ethereum types for pub-sub -use crate::{Filter, Log, RichHeader, Transaction}; +use crate::{Filter, Header, Log, Transaction}; use alloy_primitives::B256; +use alloy_serde::WithOtherFields; use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer}; /// Subscription result. @@ -9,7 +10,7 @@ use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer}; #[serde(untagged)] pub enum SubscriptionResult { /// New block header. - Header(Box), + Header(Box>), /// Log Log(Box), /// Transaction hash From 155914b0e069edd9715d69f3e297971868cd4ad8 Mon Sep 17 00:00:00 2001 From: Roy <42067944+royvardhan@users.noreply.github.com> Date: Mon, 26 Aug 2024 15:47:07 +0530 Subject: [PATCH 100/186] feat: add erc4337 endpoint methods to provider (#1176) * feat: add eip4337 eth_sendUserOperation method to provider * chore: serde rename all eip4337 operation * chore: use actual entry address for eth eip4337 * chore: nightly fmt * add feature * fix: user op elements in test * chore: rename eip to erc * chore: rename eip4337 files to erc4337 * chore: resolve pr comment * fix: address parse * feat: add new endpoints * feat: add gas estimate endpoint * chore: add err code * chore: use packed User Operation * chore: update tests * feat: combine user op for both old and new entry points * fix: clippy and docs ci * fix: docs * fix: geth tests * fix: rm tests --------- Co-authored-by: Matthias Seitz --- crates/provider/Cargo.toml | 1 + crates/provider/src/ext/erc4337.rs | 96 ++++++++++++++++ crates/provider/src/ext/mod.rs | 5 + crates/rpc-types-eth/CHANGELOG.md | 6 +- crates/rpc-types-eth/src/eip4337.rs | 41 ------- crates/rpc-types-eth/src/erc4337.rs | 171 ++++++++++++++++++++++++++++ crates/rpc-types-eth/src/lib.rs | 6 +- 7 files changed, 281 insertions(+), 45 deletions(-) create mode 100644 crates/provider/src/ext/erc4337.rs delete mode 100644 crates/rpc-types-eth/src/eip4337.rs create mode 100644 crates/rpc-types-eth/src/erc4337.rs diff --git a/crates/provider/Cargo.toml b/crates/provider/Cargo.toml index c671cd2f263..164c442100f 100644 --- a/crates/provider/Cargo.toml +++ b/crates/provider/Cargo.toml @@ -98,6 +98,7 @@ anvil-node = [ "dep:alloy-signer-local", ] debug-api = ["dep:alloy-rpc-types-trace"] +erc4337-api = [] engine-api = ["dep:alloy-rpc-types-engine"] net-api = [] trace-api = ["dep:alloy-rpc-types-trace"] diff --git a/crates/provider/src/ext/erc4337.rs b/crates/provider/src/ext/erc4337.rs new file mode 100644 index 00000000000..ffd0b050dd3 --- /dev/null +++ b/crates/provider/src/ext/erc4337.rs @@ -0,0 +1,96 @@ +use crate::Provider; +use alloy_network::Network; +use alloy_primitives::{Address, Bytes}; +use alloy_rpc_types_eth::erc4337::{ + SendUserOperation, SendUserOperationResponse, UserOperationGasEstimation, UserOperationReceipt, +}; +use alloy_transport::{Transport, TransportResult}; + +/// ERC-4337 Account Abstraction API +/// +/// This module provides support for the `eth_sendUserOperation` RPC method +/// as defined in ERC-4337. +#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)] +pub trait Erc4337Api: Send + Sync { + /// Sends a user operation to the bundler, as defined in ERC-4337. + /// + /// Entry point changes based on the user operation type. + async fn send_user_operation( + &self, + user_op: SendUserOperation, + entry_point: Address, + ) -> TransportResult; + + /// Returns the list of supported entry points. + async fn supported_entry_points(&self) -> TransportResult>; + + /// Returns the receipt for any user operation. + /// + /// Hash is the same returned by any user operation. + async fn get_user_operation_receipt( + &self, + user_op_hash: Bytes, + ) -> TransportResult; + + /// Estimates the gas for a user operation. + /// + /// Entry point changes based on the user operation type. + async fn estimate_user_operation_gas( + &self, + user_op: SendUserOperation, + entry_point: Address, + ) -> TransportResult; +} + +#[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait::async_trait)] +impl Erc4337Api for P +where + N: Network, + T: Transport + Clone, + P: Provider, +{ + async fn send_user_operation( + &self, + user_op: SendUserOperation, + entry_point: Address, + ) -> TransportResult { + match user_op { + SendUserOperation::EntryPointV06(user_op) => { + self.client().request("eth_sendUserOperation", (user_op, entry_point)).await + } + SendUserOperation::EntryPointV07(packed_user_op) => { + self.client().request("eth_sendUserOperation", (packed_user_op, entry_point)).await + } + } + } + + async fn supported_entry_points(&self) -> TransportResult> { + self.client().request("eth_supportedEntryPoints", ()).await + } + + async fn get_user_operation_receipt( + &self, + user_op_hash: Bytes, + ) -> TransportResult { + self.client().request("eth_getUserOperationReceipt", (user_op_hash,)).await + } + + async fn estimate_user_operation_gas( + &self, + user_op: SendUserOperation, + entry_point: Address, + ) -> TransportResult { + match user_op { + SendUserOperation::EntryPointV06(user_op) => { + self.client().request("eth_estimateUserOperationGas", (user_op, entry_point)).await + } + SendUserOperation::EntryPointV07(packed_user_op) => { + self.client() + .request("eth_estimateUserOperationGas", (packed_user_op, entry_point)) + .await + } + } + } +} diff --git a/crates/provider/src/ext/mod.rs b/crates/provider/src/ext/mod.rs index 7b6c0ffc1bf..a5f5c185a20 100644 --- a/crates/provider/src/ext/mod.rs +++ b/crates/provider/src/ext/mod.rs @@ -39,3 +39,8 @@ pub use rpc::RpcApi; mod txpool; #[cfg(feature = "txpool-api")] pub use txpool::TxPoolApi; + +#[cfg(feature = "erc4337-api")] +mod erc4337; +#[cfg(feature = "erc4337-api")] +pub use erc4337::Erc4337Api; diff --git a/crates/rpc-types-eth/CHANGELOG.md b/crates/rpc-types-eth/CHANGELOG.md index 132541f26d3..79ffa4ceb88 100644 --- a/crates/rpc-types-eth/CHANGELOG.md +++ b/crates/rpc-types-eth/CHANGELOG.md @@ -19,7 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Eth_simulateV1 Request / Response types ([#1042](https://github.com/alloy-rs/alloy/issues/1042)) - Feat(rpc-type-eth) convert vec TxReq to bundle ([#1091](https://github.com/alloy-rs/alloy/issues/1091)) -- Feat(provider) : introduction to eth_sendRawTransactionConditional RPC endpoint type ([#1009](https://github.com/alloy-rs/alloy/issues/1009)) +- Feat(provider) : introduction to eth_sendRawTransactionConditional RPC endpoint type ([#1009](https://github.com/alloy-rs/alloy/issues/1009)) - [rpc-types-eth] Serde flatten `BlobTransactionSidecar` in tx req ([#1054](https://github.com/alloy-rs/alloy/issues/1054)) - Add authorization list to rpc transaction and tx receipt types ([#1051](https://github.com/alloy-rs/alloy/issues/1051)) @@ -40,7 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Refactor - Add network-primitives ([#1101](https://github.com/alloy-rs/alloy/issues/1101)) -- Replace `U64` with `u64` ([#1057](https://github.com/alloy-rs/alloy/issues/1057)) +- Replace `U64` with `u64` ([#1057](https://github.com/alloy-rs/alloy/issues/1057)) ### Styling @@ -112,7 +112,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks - Rm unused txtype mod ([#879](https://github.com/alloy-rs/alloy/issues/879)) -- [other] Use type aliases where possible to improve clarity ([#859](https://github.com/alloy-rs/alloy/issues/859)) +- [other] Use type aliases where possible to improve clarity ([#859](https://github.com/alloy-rs/alloy/issues/859)) - [docs] Crate completeness and fix typos ([#861](https://github.com/alloy-rs/alloy/issues/861)) ### Other diff --git a/crates/rpc-types-eth/src/eip4337.rs b/crates/rpc-types-eth/src/eip4337.rs deleted file mode 100644 index 0a43da2f44f..00000000000 --- a/crates/rpc-types-eth/src/eip4337.rs +++ /dev/null @@ -1,41 +0,0 @@ -use alloy_primitives::{Address, BlockNumber, B256, U256}; -use serde::{Deserialize, Serialize}; -use std::collections::HashMap; - -/// Options for conditional raw transaction submissions. -// reference for the implementation -// See also -#[derive(Debug, Serialize, Deserialize, Clone, Default)] -#[serde(rename_all = "camelCase")] -pub struct ConditionalOptions { - /// A map of account addresses to their expected storage states. - /// Each account can have a specified storage root or explicit slot-value pairs. - #[serde(default)] - pub known_accounts: HashMap, - /// The minimal block number at which the transaction can be included. - /// `None` indicates no minimum block number constraint. - #[serde(default, skip_serializing_if = "Option::is_none")] - pub block_number_min: Option, - /// The maximal block number at which the transaction can be included. - /// `None` indicates no maximum block number constraint. - #[serde(default, skip_serializing_if = "Option::is_none")] - pub block_number_max: Option, - /// The minimal timestamp at which the transaction can be included. - /// `None` indicates no minimum timestamp constraint. - #[serde(default, skip_serializing_if = "Option::is_none")] - pub timestamp_min: Option, - /// The maximal timestamp at which the transaction can be included. - /// `None` indicates no maximum timestamp constraint. - #[serde(default, skip_serializing_if = "Option::is_none")] - pub timestamp_max: Option, -} - -/// Represents the expected state of an account for a transaction to be conditionally accepted. -#[derive(Debug, Serialize, Deserialize, Clone)] -#[serde(untagged)] -pub enum AccountStorage { - /// Expected storage root hash of the account. - RootHash(B256), - /// Explicit storage slots and their expected values. - Slots(HashMap), -} diff --git a/crates/rpc-types-eth/src/erc4337.rs b/crates/rpc-types-eth/src/erc4337.rs new file mode 100644 index 00000000000..a4a3ea201bf --- /dev/null +++ b/crates/rpc-types-eth/src/erc4337.rs @@ -0,0 +1,171 @@ +use crate::{Log, TransactionReceipt}; +use alloy_primitives::{Address, BlockNumber, Bytes, B256, U256}; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; + +/// Options for conditional raw transaction submissions. +// reference for the implementation +// See also +#[derive(Debug, Serialize, Deserialize, Clone, Default)] +#[serde(rename_all = "camelCase")] +pub struct ConditionalOptions { + /// A map of account addresses to their expected storage states. + /// Each account can have a specified storage root or explicit slot-value pairs. + #[serde(default)] + pub known_accounts: HashMap, + /// The minimal block number at which the transaction can be included. + /// `None` indicates no minimum block number constraint. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub block_number_min: Option, + /// The maximal block number at which the transaction can be included. + /// `None` indicates no maximum block number constraint. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub block_number_max: Option, + /// The minimal timestamp at which the transaction can be included. + /// `None` indicates no minimum timestamp constraint. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub timestamp_min: Option, + /// The maximal timestamp at which the transaction can be included. + /// `None` indicates no maximum timestamp constraint. + #[serde(default, skip_serializing_if = "Option::is_none")] + pub timestamp_max: Option, +} + +/// Represents the expected state of an account for a transaction to be conditionally accepted. +#[derive(Debug, Serialize, Deserialize, Clone)] +#[serde(untagged)] +pub enum AccountStorage { + /// Expected storage root hash of the account. + RootHash(B256), + /// Explicit storage slots and their expected values. + Slots(HashMap), +} + +/// [`UserOperation`] in the spec: Entry Point V0.6 +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct UserOperation { + /// The address of the smart contract account + pub sender: Address, + /// Anti-replay protection; also used as the salt for first-time account creation + pub nonce: U256, + /// Code used to deploy the account if not yet on-chain + pub init_code: Bytes, + /// Data that's passed to the sender for execution + pub call_data: Bytes, + /// Gas limit for execution phase + pub call_gas_limit: U256, + /// Gas limit for verification phase + pub verification_gas_limit: U256, + /// Gas to compensate the bundler + pub pre_verification_gas: U256, + /// Maximum fee per gas + pub max_fee_per_gas: U256, + /// Maximum priority fee per gas + pub max_priority_fee_per_gas: U256, + /// Paymaster Contract address and any extra data required for verification and execution + /// (empty for self-sponsored transaction) + pub paymaster_and_data: Bytes, + /// Used to validate a UserOperation along with the nonce during verification + pub signature: Bytes, +} + +/// [`PackedUserOperation`] in the spec: Entry Point V0.7 +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct PackedUserOperation { + /// The account making the operation. + pub sender: Address, + /// Prevents message replay attacks and serves as a randomizing element for initial user + /// registration. + pub nonce: U256, + /// Deployer contract address: Required exclusively for deploying new accounts that don't yet + /// exist on the blockchain. + pub factory: Address, + /// Factory data for the account creation process, applicable only when using a deployer + /// contract. + pub factory_data: Bytes, + /// The call data. + pub call_data: Bytes, + /// The gas limit for the call. + pub call_gas_limit: U256, + /// The gas limit for the verification. + pub verification_gas_limit: U256, + /// Prepaid gas fee: Covers the bundler's costs for initial transaction validation and data + /// transmission. + pub pre_verification_gas: U256, + /// The maximum fee per gas. + pub max_fee_per_gas: U256, + /// The maximum priority fee per gas. + pub max_priority_fee_per_gas: U256, + /// Paymaster contract address: Needed if a third party is covering transaction costs; left + /// blank for self-funded accounts. + pub paymaster: Address, + /// The gas limit for the paymaster verification. + pub paymaster_verification_gas_limit: U256, + /// The gas limit for the paymaster post-operation. + pub paymaster_post_op_gas_limit: U256, + /// The paymaster data. + pub paymaster_data: Bytes, + /// The signature of the transaction. + pub signature: Bytes, +} + +/// Send User Operation +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub enum SendUserOperation { + /// User Operation + EntryPointV06(UserOperation), + /// Packed User Operation + EntryPointV07(PackedUserOperation), +} + +/// Response to sending a user operation. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct SendUserOperationResponse { + /// The hash of the user operation. + pub user_op_hash: Bytes, +} + +/// Represents the receipt of a user operation. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct UserOperationReceipt { + /// The hash of the user operation. + pub user_op_hash: Bytes, + /// The entry point address for the user operation. + pub entry_point: Address, + /// The address of the sender of the user operation. + pub sender: Address, + /// The nonce of the user operation. + pub nonce: U256, + /// The address of the paymaster, if any. + pub paymaster: Address, + /// The actual gas cost incurred by the user operation. + pub actual_gas_cost: U256, + /// The actual gas used by the user operation. + pub actual_gas_used: U256, + /// Indicates whether the user operation was successful. + pub success: bool, + /// The reason for failure, if any. + pub reason: Bytes, + /// The logs generated by the user operation. + pub logs: Vec, + /// The transaction receipt of the user operation. + pub receipt: TransactionReceipt, +} + +/// Represents the gas estimation for a user operation. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct UserOperationGasEstimation { + /// The gas limit for the pre-verification. + pub pre_verification_gas: U256, + /// The gas limit for the verification. + pub verification_gas: U256, + /// The gas limit for the paymaster verification. + pub paymaster_verification_gas: U256, + /// The gas limit for the call. + pub call_gas_limit: U256, +} diff --git a/crates/rpc-types-eth/src/lib.rs b/crates/rpc-types-eth/src/lib.rs index 85870935fc9..27b58ae63be 100644 --- a/crates/rpc-types-eth/src/lib.rs +++ b/crates/rpc-types-eth/src/lib.rs @@ -52,6 +52,10 @@ mod work; pub use work::Work; /// This module provides implementations for EIP-4337. -pub mod eip4337; +pub mod erc4337; +pub use erc4337::{ + PackedUserOperation, SendUserOperation, SendUserOperationResponse, UserOperation, + UserOperationGasEstimation, UserOperationReceipt, +}; pub mod simulate; From cecf1b8e6f476d44d601816c17780c7fb8dc2192 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Mon, 26 Aug 2024 13:59:23 +0200 Subject: [PATCH 101/186] fix(provider): serialize no parameters as `[]` instead of `null` (#1193) * fix(provider): replace unit with empty array in `ChainStreamPoller` * fix: everywhere * doctest * alias * simpler --- crates/provider/src/chain.rs | 6 ++--- crates/provider/src/ext/admin.rs | 6 ++--- crates/provider/src/ext/anvil.rs | 14 +++++------ crates/provider/src/ext/debug.rs | 2 +- crates/provider/src/ext/net.rs | 6 ++--- crates/provider/src/ext/rpc.rs | 2 +- crates/provider/src/ext/txpool.rs | 6 ++--- crates/provider/src/provider/trait.rs | 36 ++++++++++++++------------- crates/rpc-client/README.md | 2 +- crates/rpc-client/src/client.rs | 13 ++++++++++ crates/rpc-client/src/lib.rs | 2 +- crates/rpc-client/tests/it/http.rs | 2 +- crates/rpc-client/tests/it/ipc.rs | 2 +- crates/rpc-client/tests/it/ws.rs | 2 +- 14 files changed, 58 insertions(+), 43 deletions(-) diff --git a/crates/provider/src/chain.rs b/crates/provider/src/chain.rs index d0149ba328a..b69c0f6b700 100644 --- a/crates/provider/src/chain.rs +++ b/crates/provider/src/chain.rs @@ -1,6 +1,6 @@ use alloy_network::{Ethereum, Network}; use alloy_primitives::{BlockNumber, U64}; -use alloy_rpc_client::{PollerBuilder, WeakClient}; +use alloy_rpc_client::{NoParams, PollerBuilder, WeakClient}; use alloy_rpc_types_eth::Block; use alloy_transport::{RpcError, Transport}; use async_stream::stream; @@ -19,7 +19,7 @@ const NO_BLOCK_NUMBER: BlockNumber = BlockNumber::MAX; pub(crate) struct ChainStreamPoller { client: WeakClient, - poll_task: PollerBuilder, + poll_task: PollerBuilder, next_yield: BlockNumber, known_blocks: LruCache, _phantom: PhantomData, @@ -39,7 +39,7 @@ impl ChainStreamPoller { fn with_next_yield(client: WeakClient, next_yield: BlockNumber) -> Self { Self { client: client.clone(), - poll_task: PollerBuilder::new(client, "eth_blockNumber", ()), + poll_task: PollerBuilder::new(client, "eth_blockNumber", []), next_yield, known_blocks: LruCache::new(BLOCK_CACHE_SIZE), _phantom: PhantomData, diff --git a/crates/provider/src/ext/admin.rs b/crates/provider/src/ext/admin.rs index b81d4701111..c1872f8e9ec 100644 --- a/crates/provider/src/ext/admin.rs +++ b/crates/provider/src/ext/admin.rs @@ -64,11 +64,11 @@ where } async fn peers(&self) -> TransportResult> { - self.client().request("admin_peers", ()).await + self.client().request_noparams("admin_peers").await } async fn node_info(&self) -> TransportResult { - self.client().request("admin_nodeInfo", ()).await + self.client().request_noparams("admin_nodeInfo").await } #[cfg(feature = "pubsub")] @@ -76,7 +76,7 @@ where &self, ) -> TransportResult> { self.root().pubsub_frontend()?; - let mut call = self.client().request("admin_peerEvents_subscribe", ()); + let mut call = self.client().request_noparams("admin_peerEvents_subscribe"); call.set_is_subscription(); let id = call.await?; self.root().get_subscription(id).await diff --git a/crates/provider/src/ext/anvil.rs b/crates/provider/src/ext/anvil.rs index 05a0dff61b3..9349e1eb8cd 100644 --- a/crates/provider/src/ext/anvil.rs +++ b/crates/provider/src/ext/anvil.rs @@ -166,7 +166,7 @@ where } async fn anvil_get_auto_mine(&self) -> TransportResult { - self.client().request("anvil_getAutomine", ()).await + self.client().request_noparams("anvil_getAutomine").await } async fn anvil_set_auto_mine(&self, enabled: bool) -> TransportResult<()> { @@ -190,7 +190,7 @@ where } async fn anvil_drop_all_transactions(&self) -> TransportResult<()> { - self.client().request("anvil_dropAllTransactions", ()).await + self.client().request_noparams("anvil_dropAllTransactions").await } async fn anvil_reset(&self, forking: Option) -> TransportResult<()> { @@ -239,7 +239,7 @@ where } async fn anvil_dump_state(&self) -> TransportResult { - self.client().request("anvil_dumpState", ()).await + self.client().request_noparams("anvil_dumpState").await } async fn anvil_load_state(&self, buf: Bytes) -> TransportResult { @@ -247,11 +247,11 @@ where } async fn anvil_node_info(&self) -> TransportResult { - self.client().request("anvil_nodeInfo", ()).await + self.client().request_noparams("anvil_nodeInfo").await } async fn anvil_metadata(&self) -> TransportResult { - self.client().request("anvil_metadata", ()).await + self.client().request_noparams("anvil_metadata").await } async fn anvil_remove_pool_transactions(&self, address: Address) -> TransportResult<()> { @@ -259,7 +259,7 @@ where } async fn anvil_snapshot(&self) -> TransportResult { - self.client().request("evm_snapshot", ()).await + self.client().request_noparams("evm_snapshot").await } async fn anvil_revert(&self, id: U256) -> TransportResult { @@ -287,7 +287,7 @@ where } async fn anvil_remove_block_timestamp_interval(&self) -> TransportResult { - self.client().request("anvil_removeBlockTimestampInterval", ()).await + self.client().request_noparams("anvil_removeBlockTimestampInterval").await } async fn evm_mine(&self, opts: Option) -> TransportResult { diff --git a/crates/provider/src/ext/debug.rs b/crates/provider/src/ext/debug.rs index d3252972299..07005ae5a20 100644 --- a/crates/provider/src/ext/debug.rs +++ b/crates/provider/src/ext/debug.rs @@ -153,7 +153,7 @@ where } async fn debug_get_bad_blocks(&self) -> TransportResult> { - self.client().request("debug_getBadBlocks", ()).await + self.client().request_noparams("debug_getBadBlocks").await } async fn debug_trace_chain( diff --git a/crates/provider/src/ext/net.rs b/crates/provider/src/ext/net.rs index 241dd58ac16..f1d962629ae 100644 --- a/crates/provider/src/ext/net.rs +++ b/crates/provider/src/ext/net.rs @@ -24,15 +24,15 @@ where P: Provider, { async fn net_listening(&self) -> TransportResult { - self.client().request("net_listening", ()).await + self.client().request_noparams("net_listening").await } async fn net_peer_count(&self) -> TransportResult { - self.client().request("net_peerCount", ()).map_resp(crate::utils::convert_u64).await + self.client().request_noparams("net_peerCount").map_resp(crate::utils::convert_u64).await } async fn net_version(&self) -> TransportResult { - self.client().request("net_version", ()).map_resp(crate::utils::convert_u64).await + self.client().request_noparams("net_version").map_resp(crate::utils::convert_u64).await } } diff --git a/crates/provider/src/ext/rpc.rs b/crates/provider/src/ext/rpc.rs index 317a603e807..aea6828fd6e 100644 --- a/crates/provider/src/ext/rpc.rs +++ b/crates/provider/src/ext/rpc.rs @@ -22,6 +22,6 @@ where P: Provider, { async fn rpc_modules(&self) -> TransportResult { - self.client().request("rpc_modules", ()).await + self.client().request_noparams("rpc_modules").await } } diff --git a/crates/provider/src/ext/txpool.rs b/crates/provider/src/ext/txpool.rs index 83b1d64f73e..34e497c2190 100644 --- a/crates/provider/src/ext/txpool.rs +++ b/crates/provider/src/ext/txpool.rs @@ -54,7 +54,7 @@ where N: Network, { async fn txpool_content(&self) -> TransportResult> { - self.client().request("txpool_content", ()).await + self.client().request_noparams("txpool_content").await } async fn txpool_content_from( @@ -65,11 +65,11 @@ where } async fn txpool_inspect(&self) -> TransportResult { - self.client().request("txpool_inspect", ()).await + self.client().request_noparams("txpool_inspect").await } async fn txpool_status(&self) -> TransportResult { - self.client().request("txpool_status", ()).await + self.client().request_noparams("txpool_status").await } } diff --git a/crates/provider/src/provider/trait.rs b/crates/provider/src/provider/trait.rs index 039cd9268aa..b3a86ff9431 100644 --- a/crates/provider/src/provider/trait.rs +++ b/crates/provider/src/provider/trait.rs @@ -16,7 +16,7 @@ use alloy_primitives::{ hex, Address, BlockHash, BlockNumber, Bytes, StorageKey, StorageValue, TxHash, B256, U128, U256, U64, }; -use alloy_rpc_client::{ClientRef, PollerBuilder, RpcCall, WeakClient}; +use alloy_rpc_client::{ClientRef, NoParams, PollerBuilder, RpcCall, WeakClient}; use alloy_rpc_types_eth::{ AccessListResult, BlockId, BlockNumberOrTag, EIP1186AccountProofResponse, FeeHistory, Filter, FilterChanges, Log, SyncStatus, @@ -101,17 +101,17 @@ pub trait Provider: /// Gets the accounts in the remote node. This is usually empty unless you're using a local /// node. async fn get_accounts(&self) -> TransportResult> { - self.client().request("eth_accounts", ()).await + self.client().request_noparams("eth_accounts").await } /// Returns the base fee per blob gas (blob gas price) in wei. async fn get_blob_base_fee(&self) -> TransportResult { - self.client().request("eth_blobBaseFee", ()).await.map(|fee: U128| fee.to::()) + self.client().request_noparams("eth_blobBaseFee").await.map(|fee: U128| fee.to::()) } /// Get the last block number available. - fn get_block_number(&self) -> RpcCall { - self.client().request("eth_blockNumber", ()).map_resp(crate::utils::convert_u64) + fn get_block_number(&self) -> RpcCall { + self.client().request_noparams("eth_blockNumber").map_resp(crate::utils::convert_u64) } /// Execute a smart contract call with a transaction request and state @@ -159,8 +159,8 @@ pub trait Provider: } /// Gets the chain ID. - fn get_chain_id(&self) -> RpcCall { - self.client().request("eth_chainId", ()).map_resp(crate::utils::convert_u64) + fn get_chain_id(&self) -> RpcCall { + self.client().request_noparams("eth_chainId").map_resp(crate::utils::convert_u64) } /// Create an [EIP-2930] access list. @@ -242,8 +242,8 @@ pub trait Provider: } /// Gets the current gas price in wei. - fn get_gas_price(&self) -> RpcCall { - self.client().request("eth_gasPrice", ()).map_resp(crate::utils::convert_u128) + fn get_gas_price(&self) -> RpcCall { + self.client().request_noparams("eth_gasPrice").map_resp(crate::utils::convert_u128) } /// Retrieves account information ([Account](alloy_consensus::Account)) for the given [Address] @@ -583,7 +583,7 @@ pub trait Provider: /// Returns a suggestion for the current `maxPriorityFeePerGas` in wei. async fn get_max_priority_fee_per_gas(&self) -> TransportResult { self.client() - .request("eth_maxPriorityFeePerGas", ()) + .request_noparams("eth_maxPriorityFeePerGas") .await .map(|fee: U128| fee.to::()) } @@ -594,7 +594,7 @@ pub trait Provider: /// /// See also [`watch_blocks`](Self::watch_blocks) to configure a poller. async fn new_block_filter(&self) -> TransportResult { - self.client().request("eth_newBlockFilter", ()).await + self.client().request_noparams("eth_newBlockFilter").await } /// Notify the provider that we are interested in logs that match the given filter. @@ -870,13 +870,13 @@ pub trait Provider: /// Gets syncing info. async fn syncing(&self) -> TransportResult { - self.client().request("eth_syncing", ()).await + self.client().request_noparams("eth_syncing").await } /// Gets the client version. #[doc(alias = "web3_client_version")] async fn get_client_version(&self) -> TransportResult { - self.client().request("web3_clientVersion", ()).await + self.client().request_noparams("web3_clientVersion").await } /// Gets the `Keccak-256` hash of the given data. @@ -886,8 +886,8 @@ pub trait Provider: } /// Gets the network ID. Same as `eth_chainId`. - fn get_net_version(&self) -> RpcCall { - self.client().request("net_version", ()).map_resp(crate::utils::convert_u64) + fn get_net_version(&self) -> RpcCall { + self.client().request_noparams("net_version").map_resp(crate::utils::convert_u64) } /* ---------------------------------------- raw calls --------------------------------------- */ @@ -899,9 +899,10 @@ pub trait Provider: /// ```no_run /// # async fn example(provider: impl alloy_provider::Provider) -> Result<(), Box> { /// use alloy_rpc_types_eth::BlockNumberOrTag; + /// use alloy_rpc_client::NoParams; /// /// // No parameters: `()` - /// let block_number = provider.raw_request("eth_blockNumber".into(), ()).await?; + /// let block_number = provider.raw_request("eth_blockNumber".into(), NoParams::default()).await?; /// /// // One parameter: `(param,)` or `[param]` /// let block = provider.raw_request("eth_getBlockByNumber".into(), (BlockNumberOrTag::Latest,)).await?; @@ -1253,7 +1254,8 @@ mod tests { async fn gets_block_number_with_raw_req() { init_tracing(); let provider = ProviderBuilder::new().on_anvil(); - let num: U64 = provider.raw_request("eth_blockNumber".into(), ()).await.unwrap(); + let num: U64 = + provider.raw_request("eth_blockNumber".into(), NoParams::default()).await.unwrap(); assert_eq!(0, num.to::()) } diff --git a/crates/rpc-client/README.md b/crates/rpc-client/README.md index 3c1ed3c5386..f1034ffc06c 100644 --- a/crates/rpc-client/README.md +++ b/crates/rpc-client/README.md @@ -16,7 +16,7 @@ For example, to make a simple request: let client: ReqwestClient = ClientBuilder::default().http(url); // Prepare a request to the server. -let request = client.request("eth_blockNumber", ()); +let request = client.request_noparams("eth_blockNumber"); // Poll the request to completion. let block_number = request.await.unwrap(); diff --git a/crates/rpc-client/src/client.rs b/crates/rpc-client/src/client.rs index a32e08950b2..b960239e35e 100644 --- a/crates/rpc-client/src/client.rs +++ b/crates/rpc-client/src/client.rs @@ -19,6 +19,9 @@ pub type WeakClient = Weak>; /// A borrowed [`RpcClient`]. pub type ClientRef<'a, T> = &'a RpcClientInner; +/// Parameter type of a JSON-RPC request with no parameters. +pub type NoParams = [(); 0]; + /// A JSON-RPC client. /// /// [`RpcClient`] should never be instantiated directly. Instead, use @@ -280,6 +283,16 @@ impl RpcClientInner { RpcCall::new(request, self.transport.clone()) } + /// Prepares an [`RpcCall`] with no parameters. + /// + /// See [`request`](Self::request) for more details. + pub fn request_noparams( + &self, + method: impl Into>, + ) -> RpcCall { + self.request(method, []) + } + /// Type erase the service in the transport, allowing it to be used in a /// generic context. /// diff --git a/crates/rpc-client/src/lib.rs b/crates/rpc-client/src/lib.rs index 10cab0096ab..ed98fab1702 100644 --- a/crates/rpc-client/src/lib.rs +++ b/crates/rpc-client/src/lib.rs @@ -22,7 +22,7 @@ mod call; pub use call::RpcCall; mod client; -pub use client::{ClientRef, RpcClient, RpcClientInner, WeakClient}; +pub use client::{ClientRef, NoParams, RpcClient, RpcClientInner, WeakClient}; mod poller; pub use poller::{PollChannel, PollerBuilder}; diff --git a/crates/rpc-client/tests/it/http.rs b/crates/rpc-client/tests/it/http.rs index c7432939452..bc399ca3dfc 100644 --- a/crates/rpc-client/tests/it/http.rs +++ b/crates/rpc-client/tests/it/http.rs @@ -7,7 +7,7 @@ async fn it_makes_a_request() { let anvil = Anvil::new().spawn(); let url = anvil.endpoint(); let client = ClientBuilder::default().http(url.parse().unwrap()); - let req: RpcCall<_, (), U64> = client.request("eth_blockNumber", ()); + let req: RpcCall<_, _, U64> = client.request_noparams("eth_blockNumber"); let timeout = tokio::time::timeout(std::time::Duration::from_secs(2), req); let res = timeout.await.unwrap().unwrap(); assert_eq!(res.to::(), 0); diff --git a/crates/rpc-client/tests/it/ipc.rs b/crates/rpc-client/tests/it/ipc.rs index bd13520455a..a34484e7ea4 100644 --- a/crates/rpc-client/tests/it/ipc.rs +++ b/crates/rpc-client/tests/it/ipc.rs @@ -17,7 +17,7 @@ async fn it_makes_a_request() { let connect = IpcConnect::new(geth.ipc_endpoint()); let client = ClientBuilder::default().pubsub(connect).await.unwrap(); - let req: RpcCall<_, (), U64> = client.request("eth_blockNumber", ()); + let req: RpcCall<_, _, U64> = client.request_noparams("eth_blockNumber"); let timeout = tokio::time::timeout(std::time::Duration::from_secs(2), req); let res = timeout.await.unwrap().unwrap(); assert!(res.to::() <= 3); diff --git a/crates/rpc-client/tests/it/ws.rs b/crates/rpc-client/tests/it/ws.rs index 5ce7e70c99a..d1286b44180 100644 --- a/crates/rpc-client/tests/it/ws.rs +++ b/crates/rpc-client/tests/it/ws.rs @@ -9,7 +9,7 @@ async fn it_makes_a_request() { let url = anvil.ws_endpoint(); let connector = WsConnect { url: url.parse().unwrap(), auth: None }; let client = ClientBuilder::default().pubsub(connector).await.unwrap(); - let req: RpcCall<_, (), U64> = client.request("eth_blockNumber", ()); + let req: RpcCall<_, _, U64> = client.request_noparams("eth_blockNumber"); let timeout = tokio::time::timeout(std::time::Duration::from_secs(2), req); let res = timeout.await.unwrap().unwrap(); assert_eq!(res.to::(), 0); From 65c73eb6b6a67792a0271b5eed61afe8df4504e8 Mon Sep 17 00:00:00 2001 From: DaniPopes <57450786+DaniPopes@users.noreply.github.com> Date: Mon, 26 Aug 2024 14:15:15 +0200 Subject: [PATCH 102/186] =?UTF-8?q?chore:=20clippy=20f=C3=BCr=20docs=20(#1?= =?UTF-8?q?194)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit chore: clippy --- crates/eips/src/eip1898.rs | 10 ++++------ crates/eips/src/eip2718.rs | 16 +++++++++------- crates/eips/src/eip4844/builder.rs | 9 +++++---- crates/genesis/src/lib.rs | 1 + crates/json-rpc/src/notification.rs | 5 +++-- crates/json-rpc/src/packet.rs | 7 ++++--- crates/json-rpc/src/request.rs | 9 +++++---- crates/provider/src/fillers/join_fill.rs | 7 ++++--- crates/provider/src/layers/anvil.rs | 9 +++++---- crates/provider/src/utils.rs | 6 ++++-- crates/rpc-types-beacon/src/relay.rs | 14 ++++++++------ crates/rpc-types-engine/src/jwt.rs | 2 ++ crates/rpc-types-eth/src/simulate.rs | 1 + crates/rpc-types-mev/src/common.rs | 5 +++-- crates/rpc-types-trace/src/filter.rs | 8 +++++--- crates/rpc-types-trace/src/geth/mod.rs | 4 +++- 16 files changed, 66 insertions(+), 47 deletions(-) diff --git a/crates/eips/src/eip1898.rs b/crates/eips/src/eip1898.rs index 4d1544a0bab..f7c02b16986 100644 --- a/crates/eips/src/eip1898.rs +++ b/crates/eips/src/eip1898.rs @@ -15,12 +15,10 @@ use serde::{ Deserialize, Deserializer, Serialize, Serializer, }; -/// A block hash which may have -/// a boolean requireCanonical field. -/// If false, an RPC call should raise if a block -/// matching the hash is not found. -/// If true, an RPC call should additionally raise if -/// the block is not in the canonical chain. +/// A block hash which may have a boolean requireCanonical field. +/// +/// If false, an RPC call should raise if a block matching the hash is not found. +/// If true, an RPC call should additionally raise if the block is not in the canonical chain. /// #[derive(Clone, Copy, Debug, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize))] diff --git a/crates/eips/src/eip2718.rs b/crates/eips/src/eip2718.rs index daa75fe20c2..13e44111d1a 100644 --- a/crates/eips/src/eip2718.rs +++ b/crates/eips/src/eip2718.rs @@ -143,9 +143,10 @@ pub trait Decodable2718: Sized { } } -/// Encoding trait for [EIP-2718] envelopes. These envelopes wrap a transaction -/// or a receipt with a type flag. [EIP-2718] encodings are used by the -/// `eth_sendRawTransaction` RPC call, the Ethereum block header's tries, and the +/// Encoding trait for [EIP-2718] envelopes. +/// +/// These envelopes wrap a transaction or a receipt with a type flag. [EIP-2718] encodings are used +/// by the `eth_sendRawTransaction` RPC call, the Ethereum block header's tries, and the /// peer-to-peer protocol. /// /// Users should rarely import this trait, and should instead prefer letting the @@ -224,10 +225,11 @@ pub trait Encodable2718: Sized + Send + Sync + 'static { } } -/// An [EIP-2718] envelope, blanket implemented for types that impl -/// [`Encodable2718`] and [`Decodable2718`]. This envelope is a wrapper around -/// a transaction, or a receipt, or any other type that is differentiated by an -/// EIP-2718 transaction type. +/// An [EIP-2718] envelope, blanket implemented for types that impl [`Encodable2718`] and +/// [`Decodable2718`]. +/// +/// This envelope is a wrapper around a transaction, or a receipt, or any other type that is +/// differentiated by an EIP-2718 transaction type. /// /// [EIP-2718]: https://eips.ethereum.org/EIPS/eip-2718 pub trait Eip2718Envelope: Decodable2718 + Encodable2718 {} diff --git a/crates/eips/src/eip4844/builder.rs b/crates/eips/src/eip4844/builder.rs index 8cddb034a85..75e9a83eee5 100644 --- a/crates/eips/src/eip4844/builder.rs +++ b/crates/eips/src/eip4844/builder.rs @@ -132,10 +132,11 @@ impl PartialSidecar { } } -/// A strategy for coding and decoding data into sidecars. Coder instances are -/// responsible for encoding and decoding data into and from the sidecar. They -/// are called by the [`SidecarBuilder`] during the [`ingest`], -/// [`take`], and (if `c_kzg` feature enabled) `build` methods. +/// A strategy for coding and decoding data into sidecars. +/// +/// Coder instances are responsible for encoding and decoding data into and from the sidecar. They +/// are called by the [`SidecarBuilder`] during the [`ingest`], [`take`], and (if `c_kzg` feature +/// enabled) `build` methods. /// /// This trait allows different downstream users to use different bit-packing /// strategies. For example, a simple coder might only use the last 31 bytes of diff --git a/crates/genesis/src/lib.rs b/crates/genesis/src/lib.rs index 76407a08a2e..05c185ec763 100644 --- a/crates/genesis/src/lib.rs +++ b/crates/genesis/src/lib.rs @@ -567,6 +567,7 @@ pub struct CliqueConfig { } /// Consensus configuration for Parlia. +/// /// Parlia is the consensus engine for BNB Smart Chain. /// For the general introduction: /// For the specification: diff --git a/crates/json-rpc/src/notification.rs b/crates/json-rpc/src/notification.rs index 743f5a2dc34..e1af087127b 100644 --- a/crates/json-rpc/src/notification.rs +++ b/crates/json-rpc/src/notification.rs @@ -25,8 +25,9 @@ pub struct EthNotification> { pub result: T, } -/// An item received over an Ethereum pubsub transport. Ethereum pubsub uses a -/// non-standard JSON-RPC notification format. An item received over a pubsub +/// An item received over an Ethereum pubsub transport. +/// +/// Ethereum pubsub uses a non-standard JSON-RPC notification format. An item received over a pubsub /// transport may be a JSON-RPC response or an Ethereum-style notification. #[derive(Clone, Debug)] pub enum PubSubItem { diff --git a/crates/json-rpc/src/packet.rs b/crates/json-rpc/src/packet.rs index 38f1edabe26..e3d7509aad8 100644 --- a/crates/json-rpc/src/packet.rs +++ b/crates/json-rpc/src/packet.rs @@ -194,9 +194,10 @@ where } } -/// A [`BorrowedResponsePacket`] is a [`ResponsePacket`] that has been partially -/// deserialized, borrowing its contents from the deserializer. This is used -/// primarily for intermediate deserialization. Most users will not require it. +/// A [`BorrowedResponsePacket`] is a [`ResponsePacket`] that has been partially deserialized, +/// borrowing its contents from the deserializer. +/// +/// This is used primarily for intermediate deserialization. Most users will not require it. /// /// See the [top-level docs] for more info. /// diff --git a/crates/json-rpc/src/request.rs b/crates/json-rpc/src/request.rs index 0bc74ffbdb5..bc8fb11b4e7 100644 --- a/crates/json-rpc/src/request.rs +++ b/crates/json-rpc/src/request.rs @@ -80,10 +80,11 @@ impl Request { } } -/// A [`Request`] that has been partially serialized. The request parameters -/// have been serialized, and are represented as a boxed [`RawValue`]. This is -/// useful for collections containing many requests, as it erases the `Param` -/// type. It can be created with [`Request::box_params()`]. +/// A [`Request`] that has been partially serialized. +/// +/// The request parameters have been serialized, and are represented as a boxed [`RawValue`]. This +/// is useful for collections containing many requests, as it erases the `Param` type. It can be +/// created with [`Request::box_params()`]. /// /// See the [top-level docs] for more info. /// diff --git a/crates/provider/src/fillers/join_fill.rs b/crates/provider/src/fillers/join_fill.rs index 7aee2419e59..3709e96eb3f 100644 --- a/crates/provider/src/fillers/join_fill.rs +++ b/crates/provider/src/fillers/join_fill.rs @@ -7,9 +7,10 @@ use alloy_network::Network; use alloy_transport::{Transport, TransportResult}; use futures::try_join; -/// A layer that can fill in a [`TransactionRequest`] with additional -/// information by joining two [`TxFiller`]s. This struct is itself a -/// [`TxFiller`], and can be nested to compose any number of fill layers. +/// A layer that can fill in a [`TransactionRequest`] with additional information by joining two +/// [`TxFiller`]s. +/// +/// This struct is itself a [`TxFiller`], and can be nested to compose any number of fill layers. /// /// [`TransactionRequest`]: alloy_rpc_types_eth::TransactionRequest #[derive(Clone, Copy, Debug)] diff --git a/crates/provider/src/layers/anvil.rs b/crates/provider/src/layers/anvil.rs index 26fa1e14016..3f512b67d17 100644 --- a/crates/provider/src/layers/anvil.rs +++ b/crates/provider/src/layers/anvil.rs @@ -9,10 +9,11 @@ use std::{ use crate::{Provider, ProviderLayer, RootProvider}; -/// A layer that wraps an [`Anvil`] config. The config will be used -/// to spawn an [`AnvilInstance`] when the layer is applied, or when the user -/// requests any information about the anvil node (e.g. via the -/// [`AnvilLayer::ws_endpoint_url`] method ). +/// A layer that wraps an [`Anvil`] config. +/// +/// The config will be used to spawn an [`AnvilInstance`] when the layer is applied, or when the +/// user requests any information about the anvil node (e.g. via the [`AnvilLayer::ws_endpoint_url`] +/// method). #[derive(Debug, Clone, Default)] pub struct AnvilLayer { anvil: Anvil, diff --git a/crates/provider/src/utils.rs b/crates/provider/src/utils.rs index ea0db81a3d1..ba2d1960723 100644 --- a/crates/provider/src/utils.rs +++ b/crates/provider/src/utils.rs @@ -40,8 +40,10 @@ fn estimate_priority_fee(rewards: &[Vec]) -> u128 { std::cmp::max(median, EIP1559_MIN_PRIORITY_FEE) } -/// The default EIP-1559 fee estimator which is based on the work by [MetaMask](https://github.com/MetaMask/core/blob/main/packages/gas-fee-controller/src/fetchGasEstimatesViaEthFeeHistory/calculateGasFeeEstimatesForPriorityLevels.ts#L56) -/// (constants for "medium" priority level are used) +/// The default EIP-1559 fee estimator. +/// +/// Based on the work by [MetaMask](https://github.com/MetaMask/core/blob/main/packages/gas-fee-controller/src/fetchGasEstimatesViaEthFeeHistory/calculateGasFeeEstimatesForPriorityLevels.ts#L56); +/// constants for "medium" priority level are used. pub fn eip1559_default_estimator( base_fee_per_gas: u128, rewards: &[Vec], diff --git a/crates/rpc-types-beacon/src/relay.rs b/crates/rpc-types-beacon/src/relay.rs index dba211b29ee..d15feb8e3a8 100644 --- a/crates/rpc-types-beacon/src/relay.rs +++ b/crates/rpc-types-beacon/src/relay.rs @@ -53,8 +53,10 @@ pub struct ValidatorRegistrationMessage { } /// Represents public information about a block sent by a builder to the relay, or from the relay to -/// the proposer. Depending on the context, value might represent the claimed value by a builder -/// (not necessarily a value confirmed by the relay). +/// the proposer. +/// +/// Depending on the context, value might represent the claimed value by a builder (not necessarily +/// a value confirmed by the relay). #[serde_as] #[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[cfg_attr(feature = "ssz", derive(ssz_derive::Encode, ssz_derive::Decode))] @@ -274,10 +276,10 @@ impl ProposerPayloadsDeliveredQuery { } } -/// OrderBy : Sort results in either ascending or descending values. * `-value` - descending value -/// (highest value first) * `value` - ascending value (lowest value first) Sort results in either -/// ascending or descending values. * `-value` - descending value (highest value first) * `value` -/// - ascending value (lowest value first) +/// Sort results in either ascending or descending values. +/// +/// - `-value` - descending value (highest value first) +/// - `value` - ascending value (lowest value first) #[derive( Default, Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd, Hash, Serialize, Deserialize, )] diff --git a/crates/rpc-types-engine/src/jwt.rs b/crates/rpc-types-engine/src/jwt.rs index c3942234f13..4e29de7fca9 100644 --- a/crates/rpc-types-engine/src/jwt.rs +++ b/crates/rpc-types-engine/src/jwt.rs @@ -88,6 +88,7 @@ const JWT_MAX_IAT_DIFF: Duration = Duration::from_secs(60); const JWT_SIGNATURE_ALGO: Algorithm = Algorithm::HS256; /// Claims in JWT are used to represent a set of information about an entity. +/// /// Claims are essentially key-value pairs that are encoded as JSON objects and included in the /// payload of a JWT. They are used to transmit information such as the identity of the entity, the /// time the JWT was issued, and the expiration time of the JWT, among others. @@ -128,6 +129,7 @@ impl Default for Claims { } /// Value-object holding a reference to a hex-encoded 256-bit secret key. +/// /// A JWT secret key is used to secure JWT-based authentication. The secret key is /// a shared secret between the server and the client and is used to calculate a digital signature /// for the JWT, which is included in the JWT along with its payload. diff --git a/crates/rpc-types-eth/src/simulate.rs b/crates/rpc-types-eth/src/simulate.rs index 715c4a99dfd..be61122456c 100644 --- a/crates/rpc-types-eth/src/simulate.rs +++ b/crates/rpc-types-eth/src/simulate.rs @@ -78,6 +78,7 @@ pub struct SimCallResult { } /// Simulation options for executing multiple blocks and transactions. +/// /// This struct configures how simulations are executed, including whether to trace token transfers, /// validate transaction sequences, and whether to return full transaction objects. #[derive(Clone, Debug, Serialize, Deserialize)] diff --git a/crates/rpc-types-mev/src/common.rs b/crates/rpc-types-mev/src/common.rs index 74a27835b7c..7395b4ed819 100644 --- a/crates/rpc-types-mev/src/common.rs +++ b/crates/rpc-types-mev/src/common.rs @@ -217,8 +217,9 @@ impl<'de> Deserialize<'de> for PrivacyHint { } } -/// Specifies the minimum percent of a given bundle's earnings to redistribute -/// for it to be included in a builder's block. +/// Specifies the minimum percent of a given bundle's earnings to redistribute for it to be included +/// in a builder's block. +/// /// Related endpoint: `mev_sendBundle`, `mev_simBundle`, `eth_sendPrivateTransaction`, /// `eth_sendPrivateRawTransaction` #[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq)] diff --git a/crates/rpc-types-trace/src/filter.rs b/crates/rpc-types-trace/src/filter.rs index 3e17294ad69..dfa56916301 100644 --- a/crates/rpc-types-trace/src/filter.rs +++ b/crates/rpc-types-trace/src/filter.rs @@ -127,9 +127,11 @@ impl AddressFilter { } } -/// `TraceFilterMatcher` is a filter used for matching `TransactionTrace` based on -/// it's action and result(if available). It allows filtering traces by their mode, from address -/// set, and to address set, and empty address set means match all addresses. +/// `TraceFilterMatcher` is a filter used for matching `TransactionTrace` based on it's action and +/// result (if available). +/// +/// It allows filtering traces by their mode, from address set, and to address set, and empty +/// address set means match all addresses. #[derive(Clone, Debug, PartialEq, Eq)] pub struct TraceFilterMatcher { mode: TraceFilterMode, diff --git a/crates/rpc-types-trace/src/geth/mod.rs b/crates/rpc-types-trace/src/geth/mod.rs index 17584518b0c..ea8c94026d5 100644 --- a/crates/rpc-types-trace/src/geth/mod.rs +++ b/crates/rpc-types-trace/src/geth/mod.rs @@ -32,7 +32,9 @@ pub struct UnexpectedTracerError(pub GethTrace); pub type TraceResult = crate::common::TraceResult; /// blockTraceResult represents the results of tracing a single block when an entire chain is being -/// traced. ref +/// traced. +/// +/// Ref #[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] pub struct BlockTraceResult { /// Block number corresponding to the trace task From 319a1d7575389893b2508a270d3842612ded2c15 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Mon, 26 Aug 2024 15:32:38 +0200 Subject: [PATCH 103/186] chore: rm Rich type (#1195) --- crates/rpc-types-eth/src/block.rs | 45 ++----------------------- crates/rpc-types-trace/src/otterscan.rs | 20 ++++------- 2 files changed, 8 insertions(+), 57 deletions(-) diff --git a/crates/rpc-types-eth/src/block.rs b/crates/rpc-types-eth/src/block.rs index c419b9c8ed0..ce83f346dc3 100644 --- a/crates/rpc-types-eth/src/block.rs +++ b/crates/rpc-types-eth/src/block.rs @@ -6,8 +6,8 @@ use alloy_network_primitives::{ }; use alloy_primitives::{Address, BlockHash, Bloom, Bytes, B256, B64, U256}; use alloy_serde::WithOtherFields; -use serde::{ser::Error, Deserialize, Serialize, Serializer}; -use std::{collections::BTreeMap, ops::Deref}; +use serde::{Deserialize, Serialize}; +use std::collections::BTreeMap; pub use alloy_eips::{ calc_blob_gasprice, calc_excess_blob_gas, BlockHashOrNumber, BlockId, BlockNumHash, @@ -249,47 +249,6 @@ impl From
for WithOtherFields
{ } } -/// Value representation with additional info -#[derive(Clone, Debug, PartialEq, Eq, Deserialize)] -pub struct Rich { - /// Standard value. - #[serde(flatten)] - pub inner: T, - /// Additional fields that should be serialized into the `Block` object - #[serde(flatten)] - pub extra_info: BTreeMap, -} - -impl Deref for Rich { - type Target = T; - fn deref(&self) -> &Self::Target { - &self.inner - } -} - -impl Serialize for Rich { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - if self.extra_info.is_empty() { - return self.inner.serialize(serializer); - } - - let inner = serde_json::to_value(&self.inner); - let extras = serde_json::to_value(&self.extra_info); - - if let (Ok(serde_json::Value::Object(mut value)), Ok(serde_json::Value::Object(extras))) = - (inner, extras) - { - value.extend(extras); - value.serialize(serializer) - } else { - Err(S::Error::custom("Unserializable structures: expected objects")) - } - } -} - /// BlockOverrides is a set of header fields to override. #[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] #[serde(default, rename_all = "camelCase", deny_unknown_fields)] diff --git a/crates/rpc-types-trace/src/otterscan.rs b/crates/rpc-types-trace/src/otterscan.rs index 7d428a64913..8c93ca9c9d9 100644 --- a/crates/rpc-types-trace/src/otterscan.rs +++ b/crates/rpc-types-trace/src/otterscan.rs @@ -4,7 +4,7 @@ //! use alloy_primitives::{Address, Bloom, Bytes, TxHash, B256, U256}; -use alloy_rpc_types_eth::{Block, Header, Rich, Transaction, TransactionReceipt, Withdrawal}; +use alloy_rpc_types_eth::{Block, Header, Transaction, TransactionReceipt, Withdrawal}; use serde::{ de::{self, Unexpected}, Deserialize, Deserializer, Serialize, Serializer, @@ -162,24 +162,16 @@ pub struct BlockDetails { pub total_fees: U256, } -impl From>> for BlockDetails { - fn from(rich_block: Rich>) -> Self { - Self { - block: rich_block.inner.into(), - issuance: Default::default(), - total_fees: U256::default(), - } +impl From> for BlockDetails { + fn from(block: Block) -> Self { + Self { block: block.into(), issuance: Default::default(), total_fees: U256::default() } } } impl BlockDetails { /// Create a new `BlockDetails` struct. - pub fn new( - rich_block: Rich>, - issuance: InternalIssuance, - total_fees: U256, - ) -> Self { - Self { block: rich_block.inner.into(), issuance, total_fees } + pub fn new(block: Block, issuance: InternalIssuance, total_fees: U256) -> Self { + Self { block: block.into(), issuance, total_fees } } } From 34d5d81dfd38f48158fdcfffcbc9debcde91012f Mon Sep 17 00:00:00 2001 From: 0xkratos <132500484+0xkr8os@users.noreply.github.com> Date: Mon, 26 Aug 2024 06:38:41 -0700 Subject: [PATCH 104/186] feat(transport): retry http errors with 503 status code (#1164) * feat(transport): retry http errors with 503 status code * chore: check style --------- Co-authored-by: Matthias Seitz --- crates/transport/src/error.rs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/crates/transport/src/error.rs b/crates/transport/src/error.rs index 17f4eda4e1e..b64f614ae2d 100644 --- a/crates/transport/src/error.rs +++ b/crates/transport/src/error.rs @@ -84,7 +84,9 @@ impl TransportErrorKind { match self { // Missing batch response errors can be retried. Self::MissingBatchResponse(_) => true, - Self::HttpError(http_err) => http_err.is_rate_limit_err(), + Self::HttpError(http_err) => { + http_err.is_rate_limit_err() || http_err.is_temporarily_unavailable() + } Self::Custom(err) => { let msg = err.to_string(); msg.contains("429 Too Many Requests") @@ -107,10 +109,13 @@ pub struct HttpError { impl HttpError { /// Checks the `status` to determine whether the request should be retried. pub const fn is_rate_limit_err(&self) -> bool { - if self.status == 429 { - return true; - } - false + self.status == 429 + } + + /// Checks the `status` to determine whether the service was temporarily unavailable and should + /// be retried. + pub const fn is_temporarily_unavailable(&self) -> bool { + self.status == 503 } } From 37586507935962bda1459c17c56777ca8647204d Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Mon, 26 Aug 2024 23:03:33 +0800 Subject: [PATCH 105/186] fix: serde for `depositReceiptVersion` (#1196) fix: deser for depositReceiptVersion --- crates/rpc-types-eth/src/transaction/optimism.rs | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/crates/rpc-types-eth/src/transaction/optimism.rs b/crates/rpc-types-eth/src/transaction/optimism.rs index 5eff353a183..f6af3d64125 100644 --- a/crates/rpc-types-eth/src/transaction/optimism.rs +++ b/crates/rpc-types-eth/src/transaction/optimism.rs @@ -7,21 +7,17 @@ use serde::{Deserialize, Serialize}; /// Optimism specific transaction fields: #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] #[doc(alias = "OptimismTxFields")] +#[serde(rename_all = "camelCase")] pub struct OptimismTransactionFields { /// Hash that uniquely identifies the source of the deposit. - #[serde(default, rename = "sourceHash", skip_serializing_if = "Option::is_none")] + #[serde(default, skip_serializing_if = "Option::is_none")] pub source_hash: Option, /// The ETH value to mint on L2 - #[serde( - default, - rename = "mint", - skip_serializing_if = "Option::is_none", - with = "alloy_serde::quantity::opt" - )] + #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] pub mint: Option, /// Field indicating whether the transaction is a system transaction, and therefore /// exempt from the L2 gas limit. - #[serde(default, rename = "isSystemTx", skip_serializing_if = "Option::is_none")] + #[serde(default, skip_serializing_if = "Option::is_none")] #[doc(alias = "is_system_transaction")] pub is_system_tx: Option, /// Deposit receipt version for Optimism deposit transactions, post-Canyon only @@ -30,7 +26,7 @@ pub struct OptimismTransactionFields { /// The deposit receipt version was introduced in Canyon to indicate an update to how /// receipt hashes should be computed when set. The state transition process /// ensures this is only set for post-Canyon deposit transactions. - #[serde(default, rename = "depositReceiptVersion", skip_serializing_if = "Option::is_none")] + #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] pub deposit_receipt_version: Option, } From 02ccb77a26f11198f1dfeacec875f7d871aa4504 Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Mon, 26 Aug 2024 17:29:27 +0200 Subject: [PATCH 106/186] chore(consensus): Add missing getter trait methods for `alloy_consensus::Transaction` (#1197) Add missing getter trait methods for alloy_consensus::Transaction --- crates/consensus/src/transaction/eip1559.rs | 10 ++++++- crates/consensus/src/transaction/eip2930.rs | 10 ++++++- crates/consensus/src/transaction/eip4844.rs | 29 +++++++++++++++++++- crates/consensus/src/transaction/eip7702.rs | 8 ++++++ crates/consensus/src/transaction/envelope.rs | 20 ++++++++++++++ crates/consensus/src/transaction/legacy.rs | 10 ++++++- crates/consensus/src/transaction/mod.rs | 18 ++++++++++-- crates/consensus/src/transaction/typed.rs | 22 ++++++++++++++- 8 files changed, 119 insertions(+), 8 deletions(-) diff --git a/crates/consensus/src/transaction/eip1559.rs b/crates/consensus/src/transaction/eip1559.rs index 1777e661ab3..c53d39b3160 100644 --- a/crates/consensus/src/transaction/eip1559.rs +++ b/crates/consensus/src/transaction/eip1559.rs @@ -1,5 +1,5 @@ use crate::{EncodableSignature, SignableTransaction, Signed, Transaction, TxType}; -use alloy_eips::eip2930::AccessList; +use alloy_eips::{eip2930::AccessList, eip7702::SignedAuthorization}; use alloy_primitives::{keccak256, Bytes, ChainId, Signature, TxKind, B256, U256}; use alloy_rlp::{BufMut, Decodable, Encodable, Header}; use core::mem; @@ -290,6 +290,10 @@ impl Transaction for TxEip1559 { self.max_priority_fee_per_gas } + fn max_fee_per_blob_gas(&self) -> Option { + None + } + fn to(&self) -> TxKind { self.to } @@ -313,6 +317,10 @@ impl Transaction for TxEip1559 { fn blob_versioned_hashes(&self) -> Option<&[B256]> { None } + + fn authorization_list(&self) -> Option<&[SignedAuthorization]> { + None + } } impl SignableTransaction for TxEip1559 { diff --git a/crates/consensus/src/transaction/eip2930.rs b/crates/consensus/src/transaction/eip2930.rs index 4cfbeb615dd..5917f3d741c 100644 --- a/crates/consensus/src/transaction/eip2930.rs +++ b/crates/consensus/src/transaction/eip2930.rs @@ -1,5 +1,5 @@ use crate::{EncodableSignature, SignableTransaction, Signed, Transaction, TxType}; -use alloy_eips::eip2930::AccessList; +use alloy_eips::{eip2930::AccessList, eip7702::SignedAuthorization}; use alloy_primitives::{keccak256, Bytes, ChainId, Signature, TxKind, B256, U256}; use alloy_rlp::{length_of_length, BufMut, Decodable, Encodable, Header}; use core::mem; @@ -254,6 +254,10 @@ impl Transaction for TxEip2930 { self.gas_price } + fn max_fee_per_blob_gas(&self) -> Option { + None + } + fn to(&self) -> TxKind { self.to } @@ -277,6 +281,10 @@ impl Transaction for TxEip2930 { fn blob_versioned_hashes(&self) -> Option<&[B256]> { None } + + fn authorization_list(&self) -> Option<&[SignedAuthorization]> { + None + } } impl SignableTransaction for TxEip2930 { diff --git a/crates/consensus/src/transaction/eip4844.rs b/crates/consensus/src/transaction/eip4844.rs index c239a12ea59..a4775200952 100644 --- a/crates/consensus/src/transaction/eip4844.rs +++ b/crates/consensus/src/transaction/eip4844.rs @@ -1,6 +1,6 @@ use crate::{EncodableSignature, SignableTransaction, Signed, Transaction, TxType}; -use alloy_eips::{eip2930::AccessList, eip4844::DATA_GAS_PER_BLOB}; +use alloy_eips::{eip2930::AccessList, eip4844::DATA_GAS_PER_BLOB, eip7702::SignedAuthorization}; use alloy_primitives::{keccak256, Address, Bytes, ChainId, Signature, TxKind, B256, U256}; use alloy_rlp::{length_of_length, BufMut, Decodable, Encodable, Header}; use core::mem; @@ -237,6 +237,13 @@ impl Transaction for TxEip4844Variant { } } + fn max_fee_per_blob_gas(&self) -> Option { + match self { + Self::TxEip4844(tx) => tx.max_fee_per_blob_gas(), + Self::TxEip4844WithSidecar(tx) => tx.max_fee_per_blob_gas(), + } + } + fn to(&self) -> TxKind { match self { Self::TxEip4844(tx) => tx.to, @@ -276,6 +283,10 @@ impl Transaction for TxEip4844Variant { Self::TxEip4844WithSidecar(tx) => tx.blob_versioned_hashes(), } } + + fn authorization_list(&self) -> Option<&[SignedAuthorization]> { + None + } } impl SignableTransaction for TxEip4844Variant { @@ -700,6 +711,10 @@ impl Transaction for TxEip4844 { self.max_priority_fee_per_gas } + fn max_fee_per_blob_gas(&self) -> Option { + Some(self.max_fee_per_blob_gas) + } + fn to(&self) -> TxKind { self.to.into() } @@ -723,6 +738,10 @@ impl Transaction for TxEip4844 { fn blob_versioned_hashes(&self) -> Option<&[B256]> { Some(&self.blob_versioned_hashes) } + + fn authorization_list(&self) -> Option<&[SignedAuthorization]> { + None + } } impl Encodable for TxEip4844 { @@ -965,6 +984,10 @@ impl Transaction for TxEip4844WithSidecar { self.tx.priority_fee_or_price() } + fn max_fee_per_blob_gas(&self) -> Option { + self.tx.max_fee_per_blob_gas() + } + fn to(&self) -> TxKind { self.tx.to() } @@ -988,6 +1011,10 @@ impl Transaction for TxEip4844WithSidecar { fn blob_versioned_hashes(&self) -> Option<&[B256]> { self.tx.blob_versioned_hashes() } + + fn authorization_list(&self) -> Option<&[SignedAuthorization]> { + None + } } #[cfg(test)] diff --git a/crates/consensus/src/transaction/eip7702.rs b/crates/consensus/src/transaction/eip7702.rs index 44bd709b373..c34a0471810 100644 --- a/crates/consensus/src/transaction/eip7702.rs +++ b/crates/consensus/src/transaction/eip7702.rs @@ -313,6 +313,10 @@ impl Transaction for TxEip7702 { self.max_priority_fee_per_gas } + fn max_fee_per_blob_gas(&self) -> Option { + None + } + fn to(&self) -> TxKind { self.to } @@ -336,6 +340,10 @@ impl Transaction for TxEip7702 { fn blob_versioned_hashes(&self) -> Option<&[B256]> { None } + + fn authorization_list(&self) -> Option<&[SignedAuthorization]> { + Some(&self.authorization_list) + } } impl SignableTransaction for TxEip7702 { diff --git a/crates/consensus/src/transaction/envelope.rs b/crates/consensus/src/transaction/envelope.rs index 5f028ab5431..79ab90b9e15 100644 --- a/crates/consensus/src/transaction/envelope.rs +++ b/crates/consensus/src/transaction/envelope.rs @@ -468,6 +468,16 @@ impl Transaction for TxEnvelope { } } + fn max_fee_per_blob_gas(&self) -> Option { + match self { + Self::Legacy(tx) => tx.tx().max_fee_per_blob_gas(), + Self::Eip2930(tx) => tx.tx().max_fee_per_blob_gas(), + Self::Eip1559(tx) => tx.tx().max_fee_per_blob_gas(), + Self::Eip4844(tx) => tx.tx().max_fee_per_blob_gas(), + Self::Eip7702(tx) => tx.tx().max_fee_per_blob_gas(), + } + } + fn input(&self) -> &[u8] { match self { Self::Legacy(tx) => tx.tx().input(), @@ -537,6 +547,16 @@ impl Transaction for TxEnvelope { Self::Eip7702(tx) => tx.tx().blob_versioned_hashes(), } } + + fn authorization_list(&self) -> Option<&[alloy_eips::eip7702::SignedAuthorization]> { + match self { + Self::Legacy(tx) => tx.tx().authorization_list(), + Self::Eip2930(tx) => tx.tx().authorization_list(), + Self::Eip1559(tx) => tx.tx().authorization_list(), + Self::Eip4844(tx) => tx.tx().authorization_list(), + Self::Eip7702(tx) => tx.tx().authorization_list(), + } + } } #[cfg(test)] diff --git a/crates/consensus/src/transaction/legacy.rs b/crates/consensus/src/transaction/legacy.rs index e45ac32ebd0..e212f93bc6d 100644 --- a/crates/consensus/src/transaction/legacy.rs +++ b/crates/consensus/src/transaction/legacy.rs @@ -1,6 +1,6 @@ use core::mem; -use alloy_eips::eip2930::AccessList; +use alloy_eips::{eip2930::AccessList, eip7702::SignedAuthorization}; use alloy_primitives::{keccak256, Bytes, ChainId, Signature, TxKind, B256, U256}; use alloy_rlp::{length_of_length, BufMut, Decodable, Encodable, Header, Result}; @@ -232,6 +232,10 @@ impl Transaction for TxLegacy { self.gas_price } + fn max_fee_per_blob_gas(&self) -> Option { + None + } + fn to(&self) -> TxKind { self.to } @@ -255,6 +259,10 @@ impl Transaction for TxLegacy { fn blob_versioned_hashes(&self) -> Option<&[B256]> { None } + + fn authorization_list(&self) -> Option<&[SignedAuthorization]> { + None + } } impl SignableTransaction for TxLegacy { diff --git a/crates/consensus/src/transaction/mod.rs b/crates/consensus/src/transaction/mod.rs index c77fa28da0d..a4bf0ebd401 100644 --- a/crates/consensus/src/transaction/mod.rs +++ b/crates/consensus/src/transaction/mod.rs @@ -1,7 +1,7 @@ //! Transaction types. use crate::Signed; -use alloy_eips::eip2930::AccessList; +use alloy_eips::{eip2930::AccessList, eip7702::SignedAuthorization}; use alloy_primitives::{keccak256, ChainId, TxKind, B256, U256}; use core::any; @@ -56,7 +56,7 @@ pub trait Transaction: any::Any + Send + Sync + 'static { /// /// For legacy transactions this is `gas_price`. /// - /// This is also commonly referred to as the "Gas Fee Cap" (`GasFeeCap`). + /// This is also commonly referred to as the "Gas Fee Cap". fn max_fee_per_gas(&self) -> u128; /// Returns the EIP-1559 Priority fee the caller is paying to the block author. @@ -64,6 +64,13 @@ pub trait Transaction: any::Any + Send + Sync + 'static { /// This will return `None` for non-EIP1559 transactions fn max_priority_fee_per_gas(&self) -> Option; + /// Max fee per blob gas for EIP-4844 transaction. + /// + /// Returns `None` for non-eip4844 transactions. + /// + /// This is also commonly referred to as the "Blob Gas Fee Cap". + fn max_fee_per_blob_gas(&self) -> Option; + /// Return the max priority fee per gas if the transaction is an EIP-1559 transaction, and /// otherwise return the gas price. /// @@ -107,13 +114,18 @@ pub trait Transaction: any::Any + Send + Sync + 'static { /// Returns the transaction type fn ty(&self) -> u8; - /// Returns the EIP2930 `access_list` for the particular transaction type. Returns `None` for + /// Returns the EIP-2930 `access_list` for the particular transaction type. Returns `None` for /// older transaction types. fn access_list(&self) -> Option<&AccessList>; /// Blob versioned hashes for eip4844 transaction. For previous transaction types this is /// `None`. fn blob_versioned_hashes(&self) -> Option<&[B256]>; + + /// Returns the [`SignedAuthorization`] list of the transaction. + /// + /// Returns `None` if this transaction is not EIP-7702. + fn authorization_list(&self) -> Option<&[SignedAuthorization]>; } /// A signable transaction. diff --git a/crates/consensus/src/transaction/typed.rs b/crates/consensus/src/transaction/typed.rs index 361b9049d31..3023fc7bdac 100644 --- a/crates/consensus/src/transaction/typed.rs +++ b/crates/consensus/src/transaction/typed.rs @@ -1,7 +1,7 @@ #[cfg(not(feature = "std"))] use alloc::vec::Vec; -use alloy_eips::eip2930::AccessList; +use alloy_eips::{eip2930::AccessList, eip7702::SignedAuthorization}; use alloy_primitives::{ChainId, TxKind, B256}; use crate::{ @@ -209,6 +209,16 @@ impl Transaction for TypedTransaction { } } + fn max_fee_per_blob_gas(&self) -> Option { + match self { + Self::Legacy(tx) => tx.max_fee_per_blob_gas(), + Self::Eip2930(tx) => tx.max_fee_per_blob_gas(), + Self::Eip1559(tx) => tx.max_fee_per_blob_gas(), + Self::Eip4844(tx) => tx.max_fee_per_blob_gas(), + Self::Eip7702(tx) => tx.max_fee_per_blob_gas(), + } + } + fn to(&self) -> TxKind { match self { Self::Legacy(tx) => tx.to(), @@ -268,6 +278,16 @@ impl Transaction for TypedTransaction { Self::Eip7702(tx) => tx.blob_versioned_hashes(), } } + + fn authorization_list(&self) -> Option<&[SignedAuthorization]> { + match self { + Self::Legacy(tx) => tx.authorization_list(), + Self::Eip2930(tx) => tx.authorization_list(), + Self::Eip1559(tx) => tx.authorization_list(), + Self::Eip4844(tx) => tx.authorization_list(), + Self::Eip7702(tx) => tx.authorization_list(), + } + } } #[cfg(feature = "serde")] From 2242ac86c5b5c13b85c0283e58e42a2c6a5a0b52 Mon Sep 17 00:00:00 2001 From: joshieDo <93316087+joshieDo@users.noreply.github.com> Date: Mon, 26 Aug 2024 21:32:57 +0100 Subject: [PATCH 107/186] fix: use `impl From for FilterBlockOption` instead of `Range` (#1199) * use RangeInclusive instead on From for FilterBlockOption * fix doctests --- crates/rpc-types-eth/src/filter.rs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/crates/rpc-types-eth/src/filter.rs b/crates/rpc-types-eth/src/filter.rs index 2adf2022d6e..ef9ecf1e963 100644 --- a/crates/rpc-types-eth/src/filter.rs +++ b/crates/rpc-types-eth/src/filter.rs @@ -12,7 +12,7 @@ use std::{ HashSet, }, hash::Hash, - ops::{Range, RangeFrom, RangeTo}, + ops::{RangeFrom, RangeInclusive, RangeToInclusive}, }; use thiserror::Error; @@ -277,16 +277,17 @@ impl From for FilterBlockOption { } } -impl> From> for FilterBlockOption { - fn from(r: Range) -> Self { - let from_block = Some(r.start.into()); - let to_block = Some(r.end.into()); +impl> From> for FilterBlockOption { + fn from(r: RangeInclusive) -> Self { + let (start, end) = r.into_inner(); + let from_block = Some(start.into()); + let to_block = Some(end.into()); Self::Range { from_block, to_block } } } -impl> From> for FilterBlockOption { - fn from(r: RangeTo) -> Self { +impl> From> for FilterBlockOption { + fn from(r: RangeToInclusive) -> Self { let to_block = Some(r.end.into()); Self::Range { from_block: Some(BlockNumberOrTag::Earliest), to_block } } @@ -371,7 +372,7 @@ impl Filter { /// ```rust /// # use alloy_rpc_types_eth::Filter; /// # fn main() { - /// let filter = Filter::new().select(0u64..100u64); + /// let filter = Filter::new().select(0u64..=100u64); /// # } /// ``` /// @@ -389,7 +390,7 @@ impl Filter { /// ```rust /// # use alloy_rpc_types_eth::Filter; /// # fn main() { - /// let filter = Filter::new().select(..1337u64); + /// let filter = Filter::new().select(..=1337u64); /// # } /// ``` #[must_use] From 61c91bca32c01330a10f7bf14fe79e6a2fce43c6 Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Tue, 27 Aug 2024 16:37:08 +0530 Subject: [PATCH 108/186] chore: bump core and rm ssz feat (#1167) * chore: bump core and rm ssz feat * bump ethereum_ssz * feat ssz in meta * bump ethereum_ssz * enable alloy-eips/ssz from rpc-types-engine --- Cargo.toml | 14 +++++++------- crates/alloy/Cargo.toml | 2 +- crates/eips/Cargo.toml | 29 ++++++++++++++++++++++++----- crates/rpc-types-beacon/Cargo.toml | 1 - crates/rpc-types-engine/Cargo.toml | 7 +------ crates/rpc-types-eth/Cargo.toml | 1 - crates/rpc-types/Cargo.toml | 8 ++------ 7 files changed, 35 insertions(+), 27 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f9fcb71e0ea..28f69bc3b12 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -69,19 +69,19 @@ alloy-transport-http = { version = "0.2", path = "crates/transport-http", defaul alloy-transport-ipc = { version = "0.2", path = "crates/transport-ipc", default-features = false } alloy-transport-ws = { version = "0.2", path = "crates/transport-ws", default-features = false } -alloy-core = { version = "0.7.7", default-features = false } -alloy-dyn-abi = { version = "0.7.7", default-features = false } -alloy-json-abi = { version = "0.7.7", default-features = false } -alloy-primitives = { version = "0.7.7", default-features = false } -alloy-sol-types = { version = "0.7.7", default-features = false } +alloy-core = { version = "0.8.0", default-features = false } +alloy-dyn-abi = { version = "0.8.0", default-features = false } +alloy-json-abi = { version = "0.8.0", default-features = false } +alloy-primitives = { version = "0.8.0", default-features = false } +alloy-sol-types = { version = "0.8.0", default-features = false } alloy-rlp = { version = "0.3", default-features = false } alloy-chains = { version = "0.1.18", default-features = false } # ethereum -ethereum_ssz_derive = "0.5" -ethereum_ssz = "0.5" +ethereum_ssz_derive = "0.7.1" +ethereum_ssz = "0.7.1" # crypto c-kzg = { version = "1.0", default-features = false } diff --git a/crates/alloy/Cargo.toml b/crates/alloy/Cargo.toml index fefbbaac9f4..a5329d9d289 100644 --- a/crates/alloy/Cargo.toml +++ b/crates/alloy/Cargo.toml @@ -259,7 +259,7 @@ getrandom = ["alloy-core/getrandom"] rand = ["alloy-core/rand"] rlp = ["alloy-core/rlp"] serde = ["alloy-core/serde", "alloy-eips?/serde", "dep:alloy-serde"] -ssz = ["alloy-core/ssz", "alloy-rpc-types?/ssz"] +ssz = ["alloy-rpc-types?/ssz"] arbitrary = [ "alloy-core/arbitrary", "alloy-consensus?/arbitrary", diff --git a/crates/eips/Cargo.toml b/crates/eips/Cargo.toml index f110ae2759d..72df135d83e 100644 --- a/crates/eips/Cargo.toml +++ b/crates/eips/Cargo.toml @@ -28,7 +28,11 @@ serde = { workspace = true, optional = true } # kzg c-kzg = { workspace = true, optional = true } -derive_more = { workspace = true, features = ["as_ref", "deref", "deref_mut"], optional = true } +derive_more = { workspace = true, features = [ + "as_ref", + "deref", + "deref_mut", +], optional = true } once_cell = { workspace = true, features = ["race", "alloc"], optional = true } sha2 = { workspace = true, optional = true } @@ -44,19 +48,34 @@ k256 = { workspace = true, optional = true } rand = { workspace = true, optional = true } [dev-dependencies] -alloy-primitives = { workspace = true, features = ["rand", "serde", "arbitrary"] } +alloy-primitives = { workspace = true, features = [ + "rand", + "serde", + "arbitrary", +] } arbitrary = { workspace = true, features = ["derive"] } serde_json.workspace = true [features] default = ["std", "kzg-sidecar"] -std = ["alloy-primitives/std", "alloy-rlp/std", "serde?/std", "c-kzg?/std", "once_cell?/std"] -serde = ["dep:alloy-serde", "dep:serde", "alloy-primitives/serde", "c-kzg?/serde"] +std = [ + "alloy-primitives/std", + "alloy-rlp/std", + "serde?/std", + "c-kzg?/std", + "once_cell?/std", +] +serde = [ + "dep:alloy-serde", + "dep:serde", + "alloy-primitives/serde", + "c-kzg?/serde", +] kzg = ["kzg-sidecar", "sha2", "dep:derive_more", "dep:c-kzg", "dep:once_cell"] kzg-sidecar = ["sha2"] sha2 = ["dep:sha2"] k256 = ["alloy-primitives/k256", "dep:k256"] -ssz = ["std", "dep:ethereum_ssz", "dep:ethereum_ssz_derive", "alloy-primitives/ssz"] +ssz = ["std", "dep:ethereum_ssz", "dep:ethereum_ssz_derive"] arbitrary = [ "std", "kzg-sidecar", diff --git a/crates/rpc-types-beacon/Cargo.toml b/crates/rpc-types-beacon/Cargo.toml index c9c06566033..092a533626a 100644 --- a/crates/rpc-types-beacon/Cargo.toml +++ b/crates/rpc-types-beacon/Cargo.toml @@ -39,6 +39,5 @@ serde_json.workspace = true ssz = [ "dep:ethereum_ssz", "dep:ethereum_ssz_derive", - "alloy-primitives/ssz", "alloy-rpc-types-engine/ssz", ] diff --git a/crates/rpc-types-engine/Cargo.toml b/crates/rpc-types-engine/Cargo.toml index 48d3c4332d8..4d50ab3b6ff 100644 --- a/crates/rpc-types-engine/Cargo.toml +++ b/crates/rpc-types-engine/Cargo.toml @@ -45,12 +45,7 @@ rand = { workspace = true, optional = true } default = ["jwt"] jwt = ["dep:jsonwebtoken", "dep:rand"] jsonrpsee-types = ["dep:jsonrpsee-types"] -ssz = [ - "dep:ethereum_ssz", - "dep:ethereum_ssz_derive", - "alloy-primitives/ssz", - "alloy-eips/ssz", -] +ssz = ["dep:ethereum_ssz", "dep:ethereum_ssz_derive", "alloy-eips/ssz"] kzg = ["alloy-consensus/kzg"] [dev-dependencies] diff --git a/crates/rpc-types-eth/Cargo.toml b/crates/rpc-types-eth/Cargo.toml index bc4c7ebb203..7c59ebf3732 100644 --- a/crates/rpc-types-eth/Cargo.toml +++ b/crates/rpc-types-eth/Cargo.toml @@ -64,5 +64,4 @@ arbitrary = [ "alloy-eips/k256", ] jsonrpsee-types = ["dep:jsonrpsee-types"] -ssz = ["alloy-primitives/ssz", "alloy-eips/ssz"] k256 = ["alloy-consensus/k256", "alloy-eips/k256"] diff --git a/crates/rpc-types/Cargo.toml b/crates/rpc-types/Cargo.toml index 0b50e49609b..bc5d58e1e27 100644 --- a/crates/rpc-types/Cargo.toml +++ b/crates/rpc-types/Cargo.toml @@ -29,7 +29,7 @@ alloy-rpc-types-eth = { workspace = true, optional = true } alloy-rpc-types-mev = { workspace = true, optional = true } alloy-rpc-types-trace = { workspace = true, optional = true } alloy-rpc-types-txpool = { workspace = true, optional = true } -serde = { workspace = true, features = ["derive", "std"]} +serde = { workspace = true, features = ["derive", "std"] } [dev-dependencies] serde_json.workspace = true @@ -51,10 +51,6 @@ jsonrpsee-types = [ "alloy-rpc-types-eth?/jsonrpsee-types", "alloy-rpc-types-engine?/jsonrpsee-types", ] -ssz = [ - "alloy-rpc-types-beacon?/ssz", - "alloy-rpc-types-engine?/ssz", - "alloy-rpc-types-eth?/ssz", -] +ssz = ["alloy-rpc-types-beacon?/ssz", "alloy-rpc-types-engine?/ssz"] k256 = ["alloy-rpc-types-eth?/k256"] kzg = ["alloy-rpc-types-engine?/kzg"] From d663b1cb705f465ad7521f2643bfb67bca8ed697 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Tue, 27 Aug 2024 17:30:02 +0400 Subject: [PATCH 109/186] fix: remove optimism-related types (#1203) * fix: remove optimism-related types * rm serde helper --- crates/rpc-types-beacon/src/payload.rs | 62 ------ crates/rpc-types-engine/src/lib.rs | 5 +- crates/rpc-types-engine/src/optimism.rs | 86 --------- crates/rpc-types-engine/src/payload.rs | 7 + crates/rpc-types-eth/src/transaction/mod.rs | 3 - .../rpc-types-eth/src/transaction/optimism.rs | 181 ------------------ 6 files changed, 8 insertions(+), 336 deletions(-) delete mode 100644 crates/rpc-types-engine/src/optimism.rs delete mode 100644 crates/rpc-types-eth/src/transaction/optimism.rs diff --git a/crates/rpc-types-beacon/src/payload.rs b/crates/rpc-types-beacon/src/payload.rs index dab8c7aa8fe..4e2056178e0 100644 --- a/crates/rpc-types-beacon/src/payload.rs +++ b/crates/rpc-types-beacon/src/payload.rs @@ -129,68 +129,6 @@ struct BeaconOptimismPayloadAttributes { gas_limit: Option, } -/// A helper module for serializing and deserializing optimism payload attributes for the beacon -/// API. -/// -/// See docs for [beacon_api_payload_attributes]. -pub mod beacon_api_payload_attributes_optimism { - use super::*; - use alloy_rpc_types_engine::{OptimismPayloadAttributes, PayloadAttributes}; - - /// Serialize the payload attributes for the beacon API. - pub fn serialize( - payload_attributes: &OptimismPayloadAttributes, - serializer: S, - ) -> Result - where - S: Serializer, - { - let beacon_api_payload_attributes = BeaconPayloadAttributes { - timestamp: payload_attributes.payload_attributes.timestamp, - prev_randao: payload_attributes.payload_attributes.prev_randao, - suggested_fee_recipient: payload_attributes.payload_attributes.suggested_fee_recipient, - withdrawals: payload_attributes.payload_attributes.withdrawals.clone(), - parent_beacon_block_root: payload_attributes - .payload_attributes - .parent_beacon_block_root, - }; - - let op_beacon_api_payload_attributes = BeaconOptimismPayloadAttributes { - payload_attributes: beacon_api_payload_attributes, - transactions: payload_attributes.transactions.clone(), - no_tx_pool: payload_attributes.no_tx_pool, - gas_limit: payload_attributes.gas_limit, - }; - - op_beacon_api_payload_attributes.serialize(serializer) - } - - /// Deserialize the payload attributes for the beacon API. - pub fn deserialize<'de, D>(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - let beacon_api_payload_attributes = - BeaconOptimismPayloadAttributes::deserialize(deserializer)?; - Ok(OptimismPayloadAttributes { - payload_attributes: PayloadAttributes { - timestamp: beacon_api_payload_attributes.payload_attributes.timestamp, - prev_randao: beacon_api_payload_attributes.payload_attributes.prev_randao, - suggested_fee_recipient: beacon_api_payload_attributes - .payload_attributes - .suggested_fee_recipient, - withdrawals: beacon_api_payload_attributes.payload_attributes.withdrawals, - parent_beacon_block_root: beacon_api_payload_attributes - .payload_attributes - .parent_beacon_block_root, - }, - transactions: beacon_api_payload_attributes.transactions, - no_tx_pool: beacon_api_payload_attributes.no_tx_pool, - gas_limit: beacon_api_payload_attributes.gas_limit, - }) - } -} - /// A helper module for serializing and deserializing the payload attributes for the beacon API. /// /// The beacon API encoded object has equivalent fields to the diff --git a/crates/rpc-types-engine/src/lib.rs b/crates/rpc-types-engine/src/lib.rs index a8ef6b7a6d1..ef9e6fd932d 100644 --- a/crates/rpc-types-engine/src/lib.rs +++ b/crates/rpc-types-engine/src/lib.rs @@ -11,13 +11,10 @@ mod forkchoice; mod identification; #[cfg(feature = "jwt")] mod jwt; -mod optimism; pub mod payload; mod transition; -pub use self::{ - cancun::*, forkchoice::*, identification::*, optimism::*, payload::*, transition::*, -}; +pub use self::{cancun::*, forkchoice::*, identification::*, payload::*, transition::*}; #[cfg(feature = "jwt")] pub use self::jwt::*; diff --git a/crates/rpc-types-engine/src/optimism.rs b/crates/rpc-types-engine/src/optimism.rs deleted file mode 100644 index cabd4e268d5..00000000000 --- a/crates/rpc-types-engine/src/optimism.rs +++ /dev/null @@ -1,86 +0,0 @@ -use crate::{BlobsBundleV1, ExecutionPayloadV3, ExecutionPayloadV4, PayloadAttributes}; -use alloy_primitives::{Bytes, B256, U256}; -use serde::{Deserialize, Serialize}; - -/// Optimism Payload Attributes -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct OptimismPayloadAttributes { - /// The payload attributes - #[serde(flatten)] - pub payload_attributes: PayloadAttributes, - /// Transactions is a field for rollups: the transactions list is forced into the block - #[serde(skip_serializing_if = "Option::is_none")] - pub transactions: Option>, - /// If true, the no transactions are taken out of the tx-pool, only transactions from the above - /// Transactions list will be included. - #[serde(skip_serializing_if = "Option::is_none")] - pub no_tx_pool: Option, - /// If set, this sets the exact gas limit the block produced with. - #[serde(skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] - pub gas_limit: Option, -} - -/// This structure maps for the return value of `engine_getPayload` of the beacon chain spec, for -/// V3. -/// -/// See also: -/// [Optimism execution payload envelope v3] -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct OptimismExecutionPayloadEnvelopeV3 { - /// Execution payload V3 - pub execution_payload: ExecutionPayloadV3, - /// The expected value to be received by the feeRecipient in wei - pub block_value: U256, - /// The blobs, commitments, and proofs associated with the executed payload. - pub blobs_bundle: BlobsBundleV1, - /// Introduced in V3, this represents a suggestion from the execution layer if the payload - /// should be used instead of an externally provided one. - pub should_override_builder: bool, - /// Ecotone parent beacon block root - pub parent_beacon_block_root: B256, -} - -/// This structure maps for the return value of `engine_getPayload` of the beacon chain spec, for -/// V4. -/// -/// See also: -/// [Optimism execution payload envelope v4] -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct OptimismExecutionPayloadEnvelopeV4 { - /// Execution payload V4 - pub execution_payload: ExecutionPayloadV4, - /// The expected value to be received by the feeRecipient in wei - pub block_value: U256, - /// The blobs, commitments, and proofs associated with the executed payload. - pub blobs_bundle: BlobsBundleV1, - /// Introduced in V3, this represents a suggestion from the execution layer if the payload - /// should be used instead of an externally provided one. - pub should_override_builder: bool, - /// Ecotone parent beacon block root - pub parent_beacon_block_root: B256, -} - -#[cfg(test)] -mod tests { - use super::*; - use crate::ExecutionPayloadInputV2; - - // - #[test] - fn deserialize_op_base_payload() { - let payload = r#"{"parentHash":"0x24e8df372a61cdcdb1a163b52aaa1785e0c869d28c3b742ac09e826bbb524723","feeRecipient":"0x4200000000000000000000000000000000000011","stateRoot":"0x9a5db45897f1ff1e620a6c14b0a6f1b3bcdbed59f2adc516a34c9a9d6baafa71","receiptsRoot":"0x8af6f74835d47835deb5628ca941d00e0c9fd75585f26dabdcb280ec7122e6af","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","prevRandao":"0xf37b24eeff594848072a05f74c8600001706c83e489a9132e55bf43a236e42ec","blockNumber":"0xe3d5d8","gasLimit":"0x17d7840","gasUsed":"0xb705","timestamp":"0x65a118c0","extraData":"0x","baseFeePerGas":"0x7a0ff32","blockHash":"0xf5c147b2d60a519b72434f0a8e082e18599021294dd9085d7597b0ffa638f1c0","withdrawals":[],"transactions":["0x7ef90159a05ba0034ffdcb246703298224564720b66964a6a69d0d7e9ffd970c546f7c048094deaddeaddeaddeaddeaddeaddeaddeaddead00019442000000000000000000000000000000000000158080830f424080b90104015d8eb900000000000000000000000000000000000000000000000000000000009e1c4a0000000000000000000000000000000000000000000000000000000065a11748000000000000000000000000000000000000000000000000000000000000000a4b479e5fa8d52dd20a8a66e468b56e993bdbffcccf729223aabff06299ab36db000000000000000000000000000000000000000000000000000000000000000400000000000000000000000073b4168cc87f35cc239200a20eb841cded23493b000000000000000000000000000000000000000000000000000000000000083400000000000000000000000000000000000000000000000000000000000f4240"]}"#; - let _payload = serde_json::from_str::(payload).unwrap(); - } - - #[test] - fn serde_roundtrip_execution_payload_envelope_v3() { - // pulled from a geth response getPayloadV3 in hive tests, modified to add a mock parent - // beacon block root. - let response = r#"{"executionPayload":{"parentHash":"0xe927a1448525fb5d32cb50ee1408461a945ba6c39bd5cf5621407d500ecc8de9","feeRecipient":"0x0000000000000000000000000000000000000000","stateRoot":"0x10f8a0830000e8edef6d00cc727ff833f064b1950afd591ae41357f97e543119","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","prevRandao":"0xe0d8b4521a7da1582a713244ffb6a86aa1726932087386e2dc7973f43fc6cb24","blockNumber":"0x1","gasLimit":"0x2ffbd2","gasUsed":"0x0","timestamp":"0x1235","extraData":"0xd883010d00846765746888676f312e32312e30856c696e7578","baseFeePerGas":"0x342770c0","blockHash":"0x44d0fa5f2f73a938ebb96a2a21679eb8dea3e7b7dd8fd9f35aa756dda8bf0a8a","transactions":[],"withdrawals":[],"blobGasUsed":"0x0","excessBlobGas":"0x0"},"blockValue":"0x0","blobsBundle":{"commitments":[],"proofs":[],"blobs":[]},"shouldOverrideBuilder":false,"parentBeaconBlockRoot":"0xdead00000000000000000000000000000000000000000000000000000000beef"}"#; - let envelope: OptimismExecutionPayloadEnvelopeV3 = serde_json::from_str(response).unwrap(); - assert_eq!(serde_json::to_string(&envelope).unwrap(), response); - } -} diff --git a/crates/rpc-types-engine/src/payload.rs b/crates/rpc-types-engine/src/payload.rs index d79701657be..11087cf5177 100644 --- a/crates/rpc-types-engine/src/payload.rs +++ b/crates/rpc-types-engine/src/payload.rs @@ -1380,4 +1380,11 @@ mod tests { serde_json::from_str(input); assert!(payload_res.is_err()); } + + // + #[test] + fn deserialize_op_base_payload() { + let payload = r#"{"parentHash":"0x24e8df372a61cdcdb1a163b52aaa1785e0c869d28c3b742ac09e826bbb524723","feeRecipient":"0x4200000000000000000000000000000000000011","stateRoot":"0x9a5db45897f1ff1e620a6c14b0a6f1b3bcdbed59f2adc516a34c9a9d6baafa71","receiptsRoot":"0x8af6f74835d47835deb5628ca941d00e0c9fd75585f26dabdcb280ec7122e6af","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","prevRandao":"0xf37b24eeff594848072a05f74c8600001706c83e489a9132e55bf43a236e42ec","blockNumber":"0xe3d5d8","gasLimit":"0x17d7840","gasUsed":"0xb705","timestamp":"0x65a118c0","extraData":"0x","baseFeePerGas":"0x7a0ff32","blockHash":"0xf5c147b2d60a519b72434f0a8e082e18599021294dd9085d7597b0ffa638f1c0","withdrawals":[],"transactions":["0x7ef90159a05ba0034ffdcb246703298224564720b66964a6a69d0d7e9ffd970c546f7c048094deaddeaddeaddeaddeaddeaddeaddeaddead00019442000000000000000000000000000000000000158080830f424080b90104015d8eb900000000000000000000000000000000000000000000000000000000009e1c4a0000000000000000000000000000000000000000000000000000000065a11748000000000000000000000000000000000000000000000000000000000000000a4b479e5fa8d52dd20a8a66e468b56e993bdbffcccf729223aabff06299ab36db000000000000000000000000000000000000000000000000000000000000000400000000000000000000000073b4168cc87f35cc239200a20eb841cded23493b000000000000000000000000000000000000000000000000000000000000083400000000000000000000000000000000000000000000000000000000000f4240"]}"#; + let _payload = serde_json::from_str::(payload).unwrap(); + } } diff --git a/crates/rpc-types-eth/src/transaction/mod.rs b/crates/rpc-types-eth/src/transaction/mod.rs index df121b03569..1624bd21656 100644 --- a/crates/rpc-types-eth/src/transaction/mod.rs +++ b/crates/rpc-types-eth/src/transaction/mod.rs @@ -21,9 +21,6 @@ pub use common::TransactionInfo; mod error; pub use error::ConversionError; -pub mod optimism; -pub use optimism::OptimismTransactionReceiptFields; - mod receipt; pub use receipt::{AnyTransactionReceipt, TransactionReceipt}; diff --git a/crates/rpc-types-eth/src/transaction/optimism.rs b/crates/rpc-types-eth/src/transaction/optimism.rs deleted file mode 100644 index f6af3d64125..00000000000 --- a/crates/rpc-types-eth/src/transaction/optimism.rs +++ /dev/null @@ -1,181 +0,0 @@ -//! Misc Optimism-specific types. - -use alloy_primitives::B256; -use alloy_serde::OtherFields; -use serde::{Deserialize, Serialize}; - -/// Optimism specific transaction fields: -#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] -#[doc(alias = "OptimismTxFields")] -#[serde(rename_all = "camelCase")] -pub struct OptimismTransactionFields { - /// Hash that uniquely identifies the source of the deposit. - #[serde(default, skip_serializing_if = "Option::is_none")] - pub source_hash: Option, - /// The ETH value to mint on L2 - #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] - pub mint: Option, - /// Field indicating whether the transaction is a system transaction, and therefore - /// exempt from the L2 gas limit. - #[serde(default, skip_serializing_if = "Option::is_none")] - #[doc(alias = "is_system_transaction")] - pub is_system_tx: Option, - /// Deposit receipt version for Optimism deposit transactions, post-Canyon only - /// - /// - /// The deposit receipt version was introduced in Canyon to indicate an update to how - /// receipt hashes should be computed when set. The state transition process - /// ensures this is only set for post-Canyon deposit transactions. - #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] - pub deposit_receipt_version: Option, -} - -/// Additional fields for Optimism transaction receipts: -#[derive(Clone, Copy, Debug, Default, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -#[doc(alias = "OptimismTxReceiptFields")] -pub struct OptimismTransactionReceiptFields { - /// Deposit nonce for deposit transactions post-regolith - #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] - pub deposit_nonce: Option, - /// Deposit receipt version for deposit transactions post-canyon - #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] - pub deposit_receipt_version: Option, - /// Present from pre-bedrock. L1 Basefee after Bedrock - #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] - pub l1_gas_price: Option, - /// Always null prior to the Ecotone hardfork. - #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] - pub l1_blob_base_fee: Option, - /// Present from pre-bedrock, deprecated as of Fjord. - #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] - pub l1_gas_used: Option, - /// Present from pre-bedrock. L1 fee for the transaction - #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] - pub l1_fee: Option, - /// Present from pre-bedrock to Ecotone. Nil after Ecotone - #[serde(default, skip_serializing_if = "Option::is_none", with = "l1_fee_scalar_serde")] - pub l1_fee_scalar: Option, - /// Always null prior to the Ecotone hardfork. - #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] - pub l1_base_fee_scalar: Option, - /// Always null prior to the Ecotone hardfork - #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] - pub l1_blob_base_fee_scalar: Option, -} - -impl From for OtherFields { - fn from(value: OptimismTransactionFields) -> Self { - serde_json::to_value(value).unwrap().try_into().unwrap() - } -} - -impl From for OtherFields { - fn from(value: OptimismTransactionReceiptFields) -> Self { - serde_json::to_value(value).unwrap().try_into().unwrap() - } -} - -/// Serialize/Deserialize l1FeeScalar to/from string -mod l1_fee_scalar_serde { - use serde::{de, Deserialize}; - - pub(super) fn serialize(value: &Option, s: S) -> Result - where - S: serde::Serializer, - { - if let Some(v) = value { - return s.serialize_str(&v.to_string()); - } - s.serialize_none() - } - - pub(super) fn deserialize<'de, D>(deserializer: D) -> Result, D::Error> - where - D: serde::Deserializer<'de>, - { - let s: Option = Option::deserialize(deserializer)?; - if let Some(s) = s { - return Ok(Some(s.parse::().map_err(de::Error::custom)?)); - } - - Ok(None) - } -} - -#[cfg(test)] -mod tests { - use super::*; - use serde_json::{json, Value}; - - #[test] - fn serialize_empty_optimism_transaction_receipt_fields_struct() { - let op_fields = OptimismTransactionReceiptFields::default(); - - let json = serde_json::to_value(op_fields).unwrap(); - assert_eq!(json, json!({})); - } - - #[test] - fn serialize_l1_fee_scalar() { - let op_fields = OptimismTransactionReceiptFields { - l1_fee_scalar: Some(0.678), - ..OptimismTransactionReceiptFields::default() - }; - - let json = serde_json::to_value(op_fields).unwrap(); - - assert_eq!(json["l1FeeScalar"], serde_json::Value::String("0.678".to_string())); - } - - #[test] - fn deserialize_l1_fee_scalar() { - let json = json!({ - "l1FeeScalar": "0.678" - }); - - let op_fields: OptimismTransactionReceiptFields = serde_json::from_value(json).unwrap(); - assert_eq!(op_fields.l1_fee_scalar, Some(0.678f64)); - - let json = json!({ - "l1FeeScalar": Value::Null - }); - - let op_fields: OptimismTransactionReceiptFields = serde_json::from_value(json).unwrap(); - assert_eq!(op_fields.l1_fee_scalar, None); - - let json = json!({}); - - let op_fields: OptimismTransactionReceiptFields = serde_json::from_value(json).unwrap(); - assert_eq!(op_fields.l1_fee_scalar, None); - } - - #[test] - fn deserialize_op_receipt() { - let s = r#"{ - "blockHash": "0x70a8a64a0f8b141718f60e49c30f027cb9e4f91753d5f13a48d8e1ad263c08bf", - "blockNumber": "0x1185e55", - "contractAddress": null, - "cumulativeGasUsed": "0xc74f5e", - "effectiveGasPrice": "0x31b41b", - "from": "0x889ebdac39408782b5165c5185c1a769b4dd3ce6", - "gasUsed": "0x5208", - "l1BaseFeeScalar": "0x8dd", - "l1BlobBaseFee": "0x1", - "l1BlobBaseFeeScalar": "0x101c12", - "l1Fee": "0x125f723f3", - "l1GasPrice": "0x50f928b4", - "l1GasUsed": "0x640", - "logs": [ - ], - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "status": "0x1", - "to": "0x7449061f45d7b39b3b80b4159286cd8682f60a3c", - "transactionHash": "0xca564948e3e825f65731424da063240eec34ba921dd117ac5d06b8c2e0b2d962", - "transactionIndex": "0x3e", - "type": "0x2" -} -"#; - let _receipt = serde_json::from_str::(s).unwrap(); - } -} From b81dec13faf5236cee25ec78d99639b8808ba312 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 27 Aug 2024 16:59:51 +0200 Subject: [PATCH 110/186] feat: add error for pre prague requests (#1204) --- crates/rpc-types-engine/src/payload.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/rpc-types-engine/src/payload.rs b/crates/rpc-types-engine/src/payload.rs index 11087cf5177..338bd0572df 100644 --- a/crates/rpc-types-engine/src/payload.rs +++ b/crates/rpc-types-engine/src/payload.rs @@ -816,7 +816,9 @@ pub enum PayloadError { /// blob transactions present in pre-prague payload. #[error("eip 7702 transactions present in pre-prague payload")] PrePragueBlockWithEip7702Transactions, - + /// requests present in pre-prague payload. + #[error("requests present in pre-prague payload")] + PrePragueBlockRequests, /// Invalid payload block hash. #[error("block hash mismatch: want {consensus}, got {execution}")] BlockHash { From 05cc4e00dc5ce9aeca01e1ffee3d7865f853ae1b Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Tue, 27 Aug 2024 19:06:09 +0400 Subject: [PATCH 111/186] fix: make `Block::hash` required (#1205) fix: make block.hash required --- crates/network-primitives/src/traits.rs | 7 +++++++ crates/network/src/lib.rs | 5 +++-- crates/provider/src/provider/trait.rs | 8 ++++---- crates/rpc-types-eth/src/block.rs | 16 ++++++++++------ 4 files changed, 24 insertions(+), 12 deletions(-) diff --git a/crates/network-primitives/src/traits.rs b/crates/network-primitives/src/traits.rs index c7409a85be8..64fc692cfa6 100644 --- a/crates/network-primitives/src/traits.rs +++ b/crates/network-primitives/src/traits.rs @@ -50,6 +50,9 @@ pub trait TransactionResponse { /// Header JSON-RPC response. pub trait HeaderResponse { + /// Block hash + fn hash(&self) -> BlockHash; + /// Block number fn number(&self) -> u64; @@ -145,6 +148,10 @@ impl BlockResponse for WithOtherFields { } impl HeaderResponse for WithOtherFields { + fn hash(&self) -> BlockHash { + self.inner.hash() + } + fn number(&self) -> u64 { self.inner.number() } diff --git a/crates/network/src/lib.rs b/crates/network/src/lib.rs index 13f0706327d..f285150b045 100644 --- a/crates/network/src/lib.rs +++ b/crates/network/src/lib.rs @@ -9,7 +9,6 @@ use alloy_consensus::TxReceipt; use alloy_eips::eip2718::{Eip2718Envelope, Eip2718Error}; use alloy_json_rpc::RpcObject; -use alloy_network_primitives::{BlockResponse, HeaderResponse}; use core::fmt::{Debug, Display}; mod transaction; @@ -25,7 +24,9 @@ mod any; pub use any::{AnyNetwork, AnyTxType}; pub use alloy_eips::eip2718; -pub use alloy_network_primitives::{self as primitives, ReceiptResponse, TransactionResponse}; +pub use alloy_network_primitives::{ + self as primitives, BlockResponse, HeaderResponse, ReceiptResponse, TransactionResponse, +}; /// Captures type info for network-specific RPC requests/responses. /// diff --git a/crates/provider/src/provider/trait.rs b/crates/provider/src/provider/trait.rs index b3a86ff9431..17393c9c35e 100644 --- a/crates/provider/src/provider/trait.rs +++ b/crates/provider/src/provider/trait.rs @@ -1277,10 +1277,10 @@ mod tests { let num = 0; let tag: BlockNumberOrTag = num.into(); let block = provider.get_block_by_number(tag, true).await.unwrap().unwrap(); - let hash = block.header.hash.unwrap(); + let hash = block.header.hash; let block = provider.get_block_by_hash(hash, BlockTransactionsKind::Full).await.unwrap().unwrap(); - assert_eq!(block.header.hash.unwrap(), hash); + assert_eq!(block.header.hash, hash); } #[tokio::test] @@ -1290,12 +1290,12 @@ mod tests { let num = 0; let tag: BlockNumberOrTag = num.into(); let block = provider.get_block_by_number(tag, true).await.unwrap().unwrap(); - let hash = block.header.hash.unwrap(); + let hash = block.header.hash; let block: Block = provider .raw_request::<(B256, bool), Block>("eth_getBlockByHash".into(), (hash, true)) .await .unwrap(); - assert_eq!(block.header.hash.unwrap(), hash); + assert_eq!(block.header.hash, hash); } #[tokio::test] diff --git a/crates/rpc-types-eth/src/block.rs b/crates/rpc-types-eth/src/block.rs index ce83f346dc3..42474cdb549 100644 --- a/crates/rpc-types-eth/src/block.rs +++ b/crates/rpc-types-eth/src/block.rs @@ -52,7 +52,7 @@ impl Block { #[serde(rename_all = "camelCase")] pub struct Header { /// Hash of the block - pub hash: Option, + pub hash: BlockHash, /// Hash of the parent pub parent_hash: B256, /// Hash of the uncles @@ -205,6 +205,10 @@ impl TryFrom
for alloy_consensus::Header { } impl HeaderResponse for Header { + fn hash(&self) -> BlockHash { + self.hash + } + fn number(&self) -> u64 { self.number } @@ -337,7 +341,7 @@ mod tests { fn serde_block() { let block = Block { header: Header { - hash: Some(B256::with_last_byte(1)), + hash: B256::with_last_byte(1), parent_hash: B256::with_last_byte(2), uncles_hash: B256::with_last_byte(3), miner: Address::with_last_byte(4), @@ -379,7 +383,7 @@ mod tests { fn serde_uncle_block() { let block = Block { header: Header { - hash: Some(B256::with_last_byte(1)), + hash: B256::with_last_byte(1), parent_hash: B256::with_last_byte(2), uncles_hash: B256::with_last_byte(3), miner: Address::with_last_byte(4), @@ -421,7 +425,7 @@ mod tests { fn serde_block_with_withdrawals_set_as_none() { let block = Block { header: Header { - hash: Some(B256::with_last_byte(1)), + hash: B256::with_last_byte(1), parent_hash: B256::with_last_byte(2), uncles_hash: B256::with_last_byte(3), miner: Address::with_last_byte(4), @@ -639,7 +643,7 @@ mod tests { let block = serde_json::from_str::(s).unwrap(); let header: alloy_consensus::Header = block.clone().header.try_into().unwrap(); let recomputed_hash = keccak256(alloy_rlp::encode(&header)); - assert_eq!(recomputed_hash, block.header.hash.unwrap()); + assert_eq!(recomputed_hash, block.header.hash); let s2 = r#"{ "baseFeePerGas":"0x886b221ad", @@ -676,6 +680,6 @@ mod tests { let block2 = serde_json::from_str::(s2).unwrap(); let header: alloy_consensus::Header = block2.clone().header.try_into().unwrap(); let recomputed_hash = keccak256(alloy_rlp::encode(&header)); - assert_eq!(recomputed_hash, block2.header.hash.unwrap()); + assert_eq!(recomputed_hash, block2.header.hash); } } From e1489b703fde94b66f5f8558925ab3f5922ee84b Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Wed, 28 Aug 2024 10:46:51 +0200 Subject: [PATCH 112/186] Implement conversion between signature types (#1198) * Implement conversion from alloy_primitives::Signature to alloy_rpc_types_eth::Signature * Simplify y-parity conversion --- crates/rpc-types-eth/src/transaction/signature.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/crates/rpc-types-eth/src/transaction/signature.rs b/crates/rpc-types-eth/src/transaction/signature.rs index 2a456b11cd3..5599fc9afc6 100644 --- a/crates/rpc-types-eth/src/transaction/signature.rs +++ b/crates/rpc-types-eth/src/transaction/signature.rs @@ -75,6 +75,17 @@ impl TryFrom for alloy_primitives::Signature { } } +impl From for Signature { + fn from(signature: alloy_primitives::Signature) -> Self { + Self { + v: U256::from(signature.v().to_u64()), + r: signature.r(), + s: signature.s(), + y_parity: Some(Parity::from(signature.v().y_parity())), + } + } +} + #[cfg(test)] mod tests { use super::*; From 7968af758d743c867470702466d07bddc63bba14 Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Wed, 28 Aug 2024 14:38:26 +0530 Subject: [PATCH 113/186] refac: rm 2930 and 7702 - use alloy-rs/eips (#1181) * refac(alloy-eips): use alloy-rs/eips for 2930 and 7702 * fix: rev * reintroduce k256 to eips + fmt nits * nit: README.md * bump eips * bump eips --- Cargo.toml | 4 + crates/alloy/Cargo.toml | 2 +- crates/consensus/Cargo.toml | 6 +- crates/eips/Cargo.toml | 30 +-- crates/eips/README.md | 2 + crates/eips/src/eip2930.rs | 208 +---------------- crates/eips/src/eip7702.rs | 2 + crates/eips/src/eip7702/auth_list.rs | 335 --------------------------- crates/eips/src/eip7702/constants.rs | 25 -- crates/eips/src/eip7702/mod.rs | 8 - crates/eips/src/lib.rs | 5 - crates/rpc-types-eth/Cargo.toml | 1 - 12 files changed, 24 insertions(+), 604 deletions(-) create mode 100644 crates/eips/src/eip7702.rs delete mode 100644 crates/eips/src/eip7702/auth_list.rs delete mode 100644 crates/eips/src/eip7702/constants.rs delete mode 100644 crates/eips/src/eip7702/mod.rs diff --git a/Cargo.toml b/Cargo.toml index 28f69bc3b12..168c30f194b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -79,6 +79,10 @@ alloy-rlp = { version = "0.3", default-features = false } alloy-chains = { version = "0.1.18", default-features = false } +# eips +alloy-eip2930 = { version = "0.1.0", default-features = false } +alloy-eip7702 = { version = "0.1.0", default-features = false } + # ethereum ethereum_ssz_derive = "0.7.1" ethereum_ssz = "0.7.1" diff --git a/crates/alloy/Cargo.toml b/crates/alloy/Cargo.toml index a5329d9d289..542924c6895 100644 --- a/crates/alloy/Cargo.toml +++ b/crates/alloy/Cargo.toml @@ -269,9 +269,9 @@ arbitrary = [ k256 = [ "alloy-core/k256", "alloy-consensus?/k256", - "alloy-eips?/k256", "alloy-network?/k256", "alloy-rpc-types?/k256", + "alloy-eips?/k256", ] kzg = ["alloy-consensus?/kzg", "alloy-rpc-types?/kzg"] eip712 = [ diff --git a/crates/consensus/Cargo.toml b/crates/consensus/Cargo.toml index a9d68626365..d4f99be9541 100644 --- a/crates/consensus/Cargo.toml +++ b/crates/consensus/Cargo.toml @@ -48,11 +48,7 @@ default = ["std"] std = ["alloy-eips/std", "c-kzg?/std"] k256 = ["alloy-primitives/k256", "alloy-eips/k256"] kzg = ["dep:c-kzg", "alloy-eips/kzg", "std"] -arbitrary = [ - "std", - "dep:arbitrary", - "alloy-eips/arbitrary", -] +arbitrary = ["std", "dep:arbitrary", "alloy-eips/arbitrary"] serde = [ "dep:serde", "alloy-primitives/serde", diff --git a/crates/eips/Cargo.toml b/crates/eips/Cargo.toml index 72df135d83e..1e327cd7de9 100644 --- a/crates/eips/Cargo.toml +++ b/crates/eips/Cargo.toml @@ -19,6 +19,10 @@ rustdoc-args = ["--cfg", "docsrs"] workspace = true [dependencies] +# eips +alloy-eip2930.workspace = true +alloy-eip7702.workspace = true + alloy-primitives = { workspace = true, features = ["rlp"] } alloy-rlp = { workspace = true, features = ["derive"] } @@ -43,9 +47,6 @@ ethereum_ssz = { workspace = true, optional = true } # arbitrary arbitrary = { workspace = true, features = ["derive"], optional = true } -# for signed authorization list arbitrary -k256 = { workspace = true, optional = true } -rand = { workspace = true, optional = true } [dev-dependencies] alloy-primitives = { workspace = true, features = [ @@ -58,29 +59,22 @@ serde_json.workspace = true [features] default = ["std", "kzg-sidecar"] -std = [ - "alloy-primitives/std", - "alloy-rlp/std", - "serde?/std", - "c-kzg?/std", - "once_cell?/std", -] -serde = [ - "dep:alloy-serde", - "dep:serde", - "alloy-primitives/serde", - "c-kzg?/serde", -] +std = ["alloy-primitives/std", "alloy-rlp/std", +"serde?/std", "c-kzg?/std", "once_cell?/std"] +serde = ["dep:alloy-serde", "dep:serde", "alloy-primitives/serde", +"c-kzg?/serde", "alloy-eip2930/serde", "alloy-eip7702/serde"] kzg = ["kzg-sidecar", "sha2", "dep:derive_more", "dep:c-kzg", "dep:once_cell"] kzg-sidecar = ["sha2"] +k256 = ["alloy-eip7702/k256"] sha2 = ["dep:sha2"] -k256 = ["alloy-primitives/k256", "dep:k256"] ssz = ["std", "dep:ethereum_ssz", "dep:ethereum_ssz_derive"] arbitrary = [ "std", "kzg-sidecar", "dep:arbitrary", - "dep:rand", "alloy-primitives/arbitrary", "alloy-serde?/arbitrary", + "alloy-eip2930/arbitrary", + "alloy-eip7702/arbitrary", + "alloy-eip7702/k256", ] diff --git a/crates/eips/README.md b/crates/eips/README.md index 4956250ee6c..ee42eee817a 100644 --- a/crates/eips/README.md +++ b/crates/eips/README.md @@ -4,6 +4,8 @@ Ethereum Improvement Proprosal (EIP) implementations. Contains constants, helpers, and basic data structures for consensus EIPs. +EIPs 2930 and 7702 are re-exported from [alloy-rs/eips](https://github.com/alloy-rs/eips). + ## Current support - [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) diff --git a/crates/eips/src/eip2930.rs b/crates/eips/src/eip2930.rs index e215eec9e04..9eda390bbec 100644 --- a/crates/eips/src/eip2930.rs +++ b/crates/eips/src/eip2930.rs @@ -1,206 +1,2 @@ -//! [EIP-2930] types. -//! -//! [EIP-2930]: https://eips.ethereum.org/EIPS/eip-2930 - -#[cfg(not(feature = "std"))] -use alloc::{string::String, vec::Vec}; - -use alloy_primitives::{Address, B256, U256}; -use alloy_rlp::{RlpDecodable, RlpDecodableWrapper, RlpEncodable, RlpEncodableWrapper}; -use core::{mem, ops::Deref}; -/// A list of addresses and storage keys that the transaction plans to access. -/// Accesses outside the list are possible, but become more expensive. -#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, RlpDecodable, RlpEncodable)] -#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] -pub struct AccessListItem { - /// Account addresses that would be loaded at the start of execution - pub address: Address, - /// Keys of storage that would be loaded at the start of execution - pub storage_keys: Vec, -} - -impl AccessListItem { - /// Calculates a heuristic for the in-memory size of the [AccessListItem]. - #[inline] - pub fn size(&self) -> usize { - mem::size_of::
() + self.storage_keys.capacity() * mem::size_of::() - } -} - -/// AccessList as defined in EIP-2930 -#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, RlpDecodableWrapper, RlpEncodableWrapper)] -#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct AccessList(pub Vec); - -impl From> for AccessList { - fn from(list: Vec) -> Self { - Self(list) - } -} - -impl From for Vec { - fn from(this: AccessList) -> Self { - this.0 - } -} - -impl Deref for AccessList { - type Target = Vec; - - fn deref(&self) -> &Self::Target { - &self.0 - } -} - -impl AccessList { - /// Converts the list into a vec, expected by revm - pub fn flattened(&self) -> Vec<(Address, Vec)> { - self.flatten().collect() - } - - /// Consumes the type and converts the list into a vec, expected by revm - pub fn into_flattened(self) -> Vec<(Address, Vec)> { - self.into_flatten().collect() - } - - /// Consumes the type and returns an iterator over the list's addresses and storage keys. - pub fn into_flatten(self) -> impl Iterator)> { - self.0.into_iter().map(|item| { - ( - item.address, - item.storage_keys.into_iter().map(|slot| U256::from_be_bytes(slot.0)).collect(), - ) - }) - } - - /// Returns an iterator over the list's addresses and storage keys. - pub fn flatten(&self) -> impl Iterator)> + '_ { - self.0.iter().map(|item| { - ( - item.address, - item.storage_keys.iter().map(|slot| U256::from_be_bytes(slot.0)).collect(), - ) - }) - } - - /// Returns the position of the given address in the access list, if present. - fn index_of_address(&self, address: Address) -> Option { - self.iter().position(|item| item.address == address) - } - - /// Checks if a specific storage slot within an account is present in the access list. - /// - /// Returns a tuple with flags for the presence of the account and the slot. - pub fn contains_storage(&self, address: Address, slot: B256) -> (bool, bool) { - self.index_of_address(address) - .map_or((false, false), |idx| (true, self.contains_storage_key_at_index(slot, idx))) - } - - /// Checks if the access list contains the specified address. - pub fn contains_address(&self, address: Address) -> bool { - self.iter().any(|item| item.address == address) - } - - /// Checks if the storage keys at the given index within an account are present in the access - /// list. - fn contains_storage_key_at_index(&self, slot: B256, index: usize) -> bool { - self.get(index).map_or(false, |entry| { - entry.storage_keys.iter().any(|storage_key| *storage_key == slot) - }) - } - - /// Adds an address to the access list and returns `true` if the operation results in a change, - /// indicating that the address was not previously present. - pub fn add_address(&mut self, address: Address) -> bool { - !self.contains_address(address) && { - self.0.push(AccessListItem { address, storage_keys: Vec::new() }); - true - } - } - - /// Calculates a heuristic for the in-memory size of the [AccessList]. - #[inline] - pub fn size(&self) -> usize { - // take into account capacity - self.0.iter().map(AccessListItem::size).sum::() - + self.0.capacity() * mem::size_of::() - } -} - -/// Access list with gas used appended. -#[derive(Clone, Debug, Default, PartialEq, Eq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] -pub struct AccessListWithGasUsed { - /// List with accounts accessed during transaction. - pub access_list: AccessList, - /// Estimated gas used with access list. - pub gas_used: U256, -} - -/// `AccessListResult` for handling errors from `eth_createAccessList` -#[derive(Clone, Debug, Default, PartialEq, Eq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] -pub struct AccessListResult { - /// List with accounts accessed during transaction. - pub access_list: AccessList, - /// Estimated gas used with access list. - pub gas_used: U256, - /// Optional error message if the transaction failed. - #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] - pub error: Option, -} - -impl AccessListResult { - /// Ensures the result is OK, returning [`AccessListWithGasUsed`] if so, or an error message if - /// not. - pub fn ensure_ok(self) -> Result { - match self.error { - Some(err) => Err(err), - None => { - Ok(AccessListWithGasUsed { access_list: self.access_list, gas_used: self.gas_used }) - } - } - } - - /// Checks if there is an error in the result. - #[inline] - pub const fn is_err(&self) -> bool { - self.error.is_some() - } -} - -#[cfg(all(test, feature = "serde"))] -mod tests { - use super::*; - - #[test] - fn access_list_serde() { - let list = AccessList(vec![ - AccessListItem { address: Address::ZERO, storage_keys: vec![B256::ZERO] }, - AccessListItem { address: Address::ZERO, storage_keys: vec![B256::ZERO] }, - ]); - let json = serde_json::to_string(&list).unwrap(); - let list2 = serde_json::from_str::(&json).unwrap(); - assert_eq!(list, list2); - } - - #[test] - fn access_list_with_gas_used() { - let list = AccessListResult { - access_list: AccessList(vec![ - AccessListItem { address: Address::ZERO, storage_keys: vec![B256::ZERO] }, - AccessListItem { address: Address::ZERO, storage_keys: vec![B256::ZERO] }, - ]), - gas_used: U256::from(100), - error: None, - }; - let json = serde_json::to_string(&list).unwrap(); - let list2 = serde_json::from_str(&json).unwrap(); - assert_eq!(list, list2); - } -} +//! Re-export the EIP-2930 types. +pub use alloy_eip2930::*; diff --git a/crates/eips/src/eip7702.rs b/crates/eips/src/eip7702.rs new file mode 100644 index 00000000000..6c4e544101d --- /dev/null +++ b/crates/eips/src/eip7702.rs @@ -0,0 +1,2 @@ +//! Re-export the EIP-7702 types. +pub use alloy_eip7702::*; diff --git a/crates/eips/src/eip7702/auth_list.rs b/crates/eips/src/eip7702/auth_list.rs deleted file mode 100644 index deb9e6c23f5..00000000000 --- a/crates/eips/src/eip7702/auth_list.rs +++ /dev/null @@ -1,335 +0,0 @@ -use core::ops::Deref; - -#[cfg(not(feature = "std"))] -use alloc::vec::Vec; -use alloy_primitives::{keccak256, Address, Signature, B256, U256}; -use alloy_rlp::{ - length_of_length, BufMut, Decodable, Encodable, Header, Result as RlpResult, RlpDecodable, - RlpEncodable, -}; -use core::hash::{Hash, Hasher}; - -/// Represents the outcome of an attempt to recover the authority from an authorization. -/// It can either be valid (containing an [`Address`]) or invalid (indicating recovery failure). -#[derive(Debug, Clone, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub enum RecoveredAuthority { - /// Indicates a successfully recovered authority address. - Valid(Address), - /// Indicates a failed recovery attempt where no valid address could be recovered. - Invalid, -} - -impl RecoveredAuthority { - /// Returns an optional address if valid. - pub const fn address(&self) -> Option
{ - match *self { - Self::Valid(address) => Some(address), - Self::Invalid => None, - } - } - - /// Returns true if the authority is valid. - pub const fn is_valid(&self) -> bool { - matches!(self, Self::Valid(_)) - } - - /// Returns true if the authority is invalid. - pub const fn is_invalid(&self) -> bool { - matches!(self, Self::Invalid) - } -} - -/// An unsigned EIP-7702 authorization. -#[derive(Debug, Clone, Hash, RlpEncodable, RlpDecodable, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] -#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] -pub struct Authorization { - /// The chain ID of the authorization. - pub chain_id: U256, - /// The address of the authorization. - pub address: Address, - /// The nonce for the authorization. - #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))] - pub nonce: u64, -} - -impl Authorization { - /// Get the `chain_id` for the authorization. - /// - /// # Note - /// - /// Implementers should check that this matches the current `chain_id` *or* is 0. - pub const fn chain_id(&self) -> U256 { - self.chain_id - } - - /// Get the `address` for the authorization. - pub const fn address(&self) -> &Address { - &self.address - } - - /// Get the `nonce` for the authorization. - pub const fn nonce(&self) -> u64 { - self.nonce - } - - /// Computes the signature hash used to sign the authorization, or recover the authority from a - /// signed authorization list item. - /// - /// The signature hash is `keccak(MAGIC || rlp([chain_id, address, nonce]))` - #[inline] - pub fn signature_hash(&self) -> B256 { - use super::constants::MAGIC; - - let mut buf = Vec::new(); - buf.put_u8(MAGIC); - self.encode(&mut buf); - - keccak256(buf) - } - - /// Convert to a signed authorization by adding a signature. - pub const fn into_signed(self, signature: Signature) -> SignedAuthorization { - SignedAuthorization { inner: self, signature } - } -} - -/// A signed EIP-7702 authorization. -#[derive(Debug, Clone, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct SignedAuthorization { - #[cfg_attr(feature = "serde", serde(flatten))] - inner: Authorization, - #[cfg_attr(feature = "serde", serde(flatten))] - signature: Signature, -} - -impl SignedAuthorization { - /// Get the `signature` for the authorization. - pub const fn signature(&self) -> &Signature { - &self.signature - } - - /// Splits the authorization into parts. - pub const fn into_parts(self) -> (Authorization, Signature) { - (self.inner, self.signature) - } - - /// Decodes the transaction from RLP bytes, including the signature. - fn decode_fields(buf: &mut &[u8]) -> RlpResult { - Ok(Self { - inner: Authorization { - chain_id: Decodable::decode(buf)?, - address: Decodable::decode(buf)?, - nonce: Decodable::decode(buf)?, - }, - signature: Signature::decode_rlp_vrs(buf)?, - }) - } - - /// Outputs the length of the transaction's fields, without a RLP header. - fn fields_len(&self) -> usize { - self.inner.chain_id.length() - + self.inner.address.length() - + self.inner.nonce.length() - + self.signature.rlp_vrs_len() - } -} - -impl Hash for SignedAuthorization { - fn hash(&self, state: &mut H) { - self.inner.hash(state); - self.signature.r().hash(state); - self.signature.s().hash(state); - self.signature.v().to_u64().hash(state); - } -} - -impl Decodable for SignedAuthorization { - fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { - let header = Header::decode(buf)?; - if !header.list { - return Err(alloy_rlp::Error::UnexpectedString); - } - Self::decode_fields(buf) - } -} - -impl Encodable for SignedAuthorization { - fn encode(&self, buf: &mut dyn BufMut) { - Header { list: true, payload_length: self.fields_len() }.encode(buf); - self.inner.chain_id.encode(buf); - self.inner.address.encode(buf); - self.inner.nonce.encode(buf); - self.signature.write_rlp_vrs(buf) - } - - fn length(&self) -> usize { - let len = self.fields_len(); - len + length_of_length(len) - } -} - -#[cfg(feature = "k256")] -impl SignedAuthorization { - /// Recover the authority for the authorization. - /// - /// # Note - /// - /// Implementers should check that the authority has no code. - pub fn recover_authority(&self) -> Result { - self.signature.recover_address_from_prehash(&self.inner.signature_hash()) - } - - /// Recover the authority and transform the signed authorization into a - /// [`RecoveredAuthorization`]. - pub fn into_recovered(self) -> RecoveredAuthorization { - let authority_result = self.recover_authority(); - let authority = - authority_result.map_or(RecoveredAuthority::Invalid, RecoveredAuthority::Valid); - - RecoveredAuthorization { inner: self.inner, authority } - } -} - -impl Deref for SignedAuthorization { - type Target = Authorization; - - fn deref(&self) -> &Self::Target { - &self.inner - } -} - -#[cfg(all(any(test, feature = "arbitrary"), feature = "k256"))] -impl<'a> arbitrary::Arbitrary<'a> for SignedAuthorization { - fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { - use k256::{ - ecdsa::{signature::hazmat::PrehashSigner, SigningKey}, - NonZeroScalar, - }; - use rand::{rngs::StdRng, SeedableRng}; - - let rng_seed = u.arbitrary::<[u8; 32]>()?; - let mut rand_gen = StdRng::from_seed(rng_seed); - let signing_key: SigningKey = NonZeroScalar::random(&mut rand_gen).into(); - - let inner = u.arbitrary::()?; - let signature_hash = inner.signature_hash(); - - let (recoverable_sig, recovery_id) = - signing_key.sign_prehash(signature_hash.as_ref()).unwrap(); - let signature = Signature::from_signature_and_parity(recoverable_sig, recovery_id) - .map_err(|_| arbitrary::Error::IncorrectFormat)?; - - Ok(Self { inner, signature }) - } -} - -/// A recovered authorization. -#[derive(Debug, Clone, Hash, Eq, PartialEq)] -#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] -pub struct RecoveredAuthorization { - #[cfg_attr(feature = "serde", serde(flatten))] - inner: Authorization, - /// The result of the authority recovery process, which can either be a valid address or - /// indicate a failure. - authority: RecoveredAuthority, -} - -impl RecoveredAuthorization { - /// Instantiate without performing recovery. This should be used carefully. - pub const fn new_unchecked(inner: Authorization, authority: RecoveredAuthority) -> Self { - Self { inner, authority } - } - - /// Returns an optional address based on the current state of the authority. - pub const fn authority(&self) -> Option
{ - self.authority.address() - } - - /// Splits the authorization into parts. - pub const fn into_parts(self) -> (Authorization, RecoveredAuthority) { - (self.inner, self.authority) - } -} - -#[cfg(feature = "k256")] -impl From for RecoveredAuthority { - fn from(value: SignedAuthorization) -> Self { - value.into_recovered().authority - } -} - -#[cfg(feature = "k256")] -impl From for RecoveredAuthorization { - fn from(value: SignedAuthorization) -> Self { - value.into_recovered() - } -} -impl Deref for RecoveredAuthorization { - type Target = Authorization; - - fn deref(&self) -> &Self::Target { - &self.inner - } -} - -#[cfg(test)] -mod tests { - use super::*; - use alloy_primitives::{hex, Signature}; - use core::str::FromStr; - - fn test_encode_decode_roundtrip(auth: Authorization) { - let mut buf = Vec::new(); - auth.encode(&mut buf); - let decoded = Authorization::decode(&mut buf.as_ref()).unwrap(); - assert_eq!(buf.len(), auth.length()); - assert_eq!(decoded, auth); - } - - #[test] - fn test_encode_decode_auth() { - // fully filled - test_encode_decode_roundtrip(Authorization { - chain_id: U256::from(1u64), - address: Address::left_padding_from(&[6]), - nonce: 1, - }); - } - - #[test] - fn test_encode_decode_signed_auth() { - let auth = SignedAuthorization { - inner: Authorization { - chain_id: U256::from(1u64), - address: Address::left_padding_from(&[6]), - nonce: 1, - }, - signature: Signature::from_str("48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c8041b").unwrap(), - }; - let mut buf = Vec::new(); - auth.encode(&mut buf); - - let expected = "f85a01940000000000000000000000000000000000000006011ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804"; - assert_eq!(hex::encode(&buf), expected); - - let decoded = SignedAuthorization::decode(&mut buf.as_ref()).unwrap(); - assert_eq!(buf.len(), auth.length()); - assert_eq!(decoded, auth); - } - - #[cfg(all(feature = "arbitrary", feature = "k256"))] - #[test] - fn test_arbitrary_auth() { - use arbitrary::Arbitrary; - let mut unstructured = arbitrary::Unstructured::new(b"unstructured auth"); - // try this multiple times - let _auth = SignedAuthorization::arbitrary(&mut unstructured).unwrap(); - let _auth = SignedAuthorization::arbitrary(&mut unstructured).unwrap(); - let _auth = SignedAuthorization::arbitrary(&mut unstructured).unwrap(); - let _auth = SignedAuthorization::arbitrary(&mut unstructured).unwrap(); - } -} diff --git a/crates/eips/src/eip7702/constants.rs b/crates/eips/src/eip7702/constants.rs deleted file mode 100644 index cc39b7f6a84..00000000000 --- a/crates/eips/src/eip7702/constants.rs +++ /dev/null @@ -1,25 +0,0 @@ -//! [EIP-7702] constants. -//! -//! [EIP-7702]: https://eips.ethereum.org/EIPS/eip-7702 - -/// Identifier for EIP7702's set code transaction. -/// -/// See also [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702). -pub const EIP7702_TX_TYPE_ID: u8 = 4; - -/// Magic number used to calculate an EIP7702 authority. -/// -/// See also [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702). -pub const MAGIC: u8 = 0x05; - -/// An additional gas cost per EIP7702 authorization list item. -/// -/// See also [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702). -pub const PER_AUTH_BASE_COST: u64 = 2500; - -/// A gas refund for EIP7702 transactions if the authority account already exists in the trie. -/// -/// The refund is `PER_EMPTY_ACCOUNT_COST - PER_AUTH_BASE_COST`. -/// -/// See also [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702). -pub const PER_EMPTY_ACCOUNT_COST: u64 = 25000; diff --git a/crates/eips/src/eip7702/mod.rs b/crates/eips/src/eip7702/mod.rs deleted file mode 100644 index 26ad27a883c..00000000000 --- a/crates/eips/src/eip7702/mod.rs +++ /dev/null @@ -1,8 +0,0 @@ -//! [EIP-7702] constants, helpers, and types. -//! -//! [EIP-7702]: https://eips.ethereum.org/EIPS/eip-7702 - -mod auth_list; -pub use auth_list::*; - -pub mod constants; diff --git a/crates/eips/src/lib.rs b/crates/eips/src/lib.rs index b1111f8eeb5..393ba4f343e 100644 --- a/crates/eips/src/lib.rs +++ b/crates/eips/src/lib.rs @@ -11,11 +11,6 @@ #[macro_use] extern crate alloc; -// To ensure no unused imports, since signed auth list requires arbitrary _and_ k256 features, but -// is only enabled using the `arbitrary` feature. -#[cfg(all(not(feature = "k256"), feature = "arbitrary"))] -use rand as _; - pub mod eip1559; pub use eip1559::calc_next_block_base_fee; diff --git a/crates/rpc-types-eth/Cargo.toml b/crates/rpc-types-eth/Cargo.toml index 7c59ebf3732..1d40c304c78 100644 --- a/crates/rpc-types-eth/Cargo.toml +++ b/crates/rpc-types-eth/Cargo.toml @@ -61,7 +61,6 @@ arbitrary = [ "alloy-primitives/arbitrary", "alloy-serde/arbitrary", "alloy-eips/arbitrary", - "alloy-eips/k256", ] jsonrpsee-types = ["dep:jsonrpsee-types"] k256 = ["alloy-consensus/k256", "alloy-eips/k256"] From 352e83bfcf537ed9519decc10b9853b2d56ace95 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 28 Aug 2024 12:20:32 +0200 Subject: [PATCH 114/186] chore: release 0.3.0 --- CHANGELOG.md | 58 +++++++++++++++++++++- Cargo.toml | 68 ++++++++++++------------- crates/alloy/CHANGELOG.md | 7 ++- crates/consensus/CHANGELOG.md | 13 ++++- crates/contract/CHANGELOG.md | 6 ++- crates/eip7547/CHANGELOG.md | 2 +- crates/eips/CHANGELOG.md | 13 ++++- crates/genesis/CHANGELOG.md | 3 +- crates/json-rpc/CHANGELOG.md | 10 +++- crates/network-primitives/CHANGELOG.md | 10 +++- crates/network/CHANGELOG.md | 15 +++++- crates/node-bindings/CHANGELOG.md | 6 ++- crates/provider/CHANGELOG.md | 18 ++++++- crates/pubsub/CHANGELOG.md | 7 ++- crates/rpc-client/CHANGELOG.md | 8 ++- crates/rpc-types-admin/CHANGELOG.md | 2 +- crates/rpc-types-anvil/CHANGELOG.md | 2 +- crates/rpc-types-beacon/CHANGELOG.md | 11 +++- crates/rpc-types-debug/CHANGELOG.md | 69 ++++++++++++++++++++++++++ crates/rpc-types-engine/CHANGELOG.md | 10 +++- crates/rpc-types-eth/CHANGELOG.md | 32 ++++++++++-- crates/rpc-types-mev/CHANGELOG.md | 3 +- crates/rpc-types-trace/CHANGELOG.md | 6 ++- crates/rpc-types-txpool/CHANGELOG.md | 6 ++- crates/rpc-types/CHANGELOG.md | 11 +++- crates/serde/CHANGELOG.md | 3 +- crates/signer-aws/CHANGELOG.md | 2 +- crates/signer-gcp/CHANGELOG.md | 8 ++- crates/signer-ledger/CHANGELOG.md | 8 ++- crates/signer-local/CHANGELOG.md | 8 ++- crates/signer-trezor/CHANGELOG.md | 2 +- crates/signer/CHANGELOG.md | 2 +- crates/transport-http/CHANGELOG.md | 2 +- crates/transport-ipc/CHANGELOG.md | 2 +- crates/transport-ws/CHANGELOG.md | 2 +- crates/transport/CHANGELOG.md | 3 +- 36 files changed, 367 insertions(+), 71 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c9a75730df..0492ace7812 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,10 +5,25 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Bug Fixes +- Make `Block::hash` required ([#1205](https://github.com/alloy-rs/alloy/issues/1205)) +- Remove optimism-related types ([#1203](https://github.com/alloy-rs/alloy/issues/1203)) +- Use `impl From for FilterBlockOption` instead of `Range` ([#1199](https://github.com/alloy-rs/alloy/issues/1199)) +- Serde for `depositReceiptVersion` ([#1196](https://github.com/alloy-rs/alloy/issues/1196)) +- [provider] Serialize no parameters as `[]` instead of `null` ([#1193](https://github.com/alloy-rs/alloy/issues/1193)) +- Change generics order for `Block` ([#1192](https://github.com/alloy-rs/alloy/issues/1192)) +- Add missing op fields ([#1187](https://github.com/alloy-rs/alloy/issues/1187)) +- Use `server_id` when unsubscribing ([#1182](https://github.com/alloy-rs/alloy/issues/1182)) +- Allow arbitrary strings in subscription ids ([#1163](https://github.com/alloy-rs/alloy/issues/1163)) +- Remove `OtherFields` from Transaction and Block ([#1154](https://github.com/alloy-rs/alloy/issues/1154)) +- [rpc-types-eth] Match 7702 in TxReceipt.status() ([#1149](https://github.com/alloy-rs/alloy/issues/1149)) +- Return more user-friendly error on tx timeout ([#1145](https://github.com/alloy-rs/alloy/issues/1145)) +- [doc] Correct order of fields ([#1139](https://github.com/alloy-rs/alloy/issues/1139)) +- Use `BlockId` superset over `BlockNumberOrTag` where applicable ([#1135](https://github.com/alloy-rs/alloy/issues/1135)) +- [rpc] Show data in when cast send result in custom error ([#1129](https://github.com/alloy-rs/alloy/issues/1129)) - Make Parity TraceResults output optional ([#1102](https://github.com/alloy-rs/alloy/issues/1102)) - Correctly trim eip7251 bytecode ([#1105](https://github.com/alloy-rs/alloy/issues/1105)) - [eips] Make SignedAuthorizationList arbitrary less fallible ([#1084](https://github.com/alloy-rs/alloy/issues/1084)) @@ -23,6 +38,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Dependencies +- Rm 2930 and 7702 - use alloy-rs/eips ([#1181](https://github.com/alloy-rs/alloy/issues/1181)) +- Bump core and rm ssz feat ([#1167](https://github.com/alloy-rs/alloy/issues/1167)) +- [deps] Bump some deps ([#1141](https://github.com/alloy-rs/alloy/issues/1141)) +- Revert "chore(deps): bump some deps" +- [deps] Bump some deps - Bump jsonrpsee 0.24 ([#1067](https://github.com/alloy-rs/alloy/issues/1067)) - [deps] Bump Trezor client to `=0.1.4` to fix signing bug ([#1045](https://github.com/alloy-rs/alloy/issues/1045)) @@ -33,6 +53,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Features +- Add error for pre prague requests ([#1204](https://github.com/alloy-rs/alloy/issues/1204)) +- [transport] Retry http errors with 503 status code ([#1164](https://github.com/alloy-rs/alloy/issues/1164)) +- Add erc4337 endpoint methods to provider ([#1176](https://github.com/alloy-rs/alloy/issues/1176)) +- Add block and transaction generics to otterscan and txpool types ([#1183](https://github.com/alloy-rs/alloy/issues/1183)) +- Make block struct generic over header type ([#1179](https://github.com/alloy-rs/alloy/issues/1179)) +- [rpc-types] `debug_executionWitness` ([#1178](https://github.com/alloy-rs/alloy/issues/1178)) +- Network-parameterized block responses ([#1106](https://github.com/alloy-rs/alloy/issues/1106)) +- Add get raw transaction by hash ([#1168](https://github.com/alloy-rs/alloy/issues/1168)) +- [geth/trace] Add field log.position ([#1150](https://github.com/alloy-rs/alloy/issues/1150)) +- Make signature methods generic over EncodableSignature ([#1138](https://github.com/alloy-rs/alloy/issues/1138)) +- Add 7702 tx enum ([#1059](https://github.com/alloy-rs/alloy/issues/1059)) +- Add authorization list to TransactionRequest ([#1125](https://github.com/alloy-rs/alloy/issues/1125)) - [engine-types] `PayloadError::PrePragueBlockWithEip7702Transactions` ([#1116](https://github.com/alloy-rs/alloy/issues/1116)) - Use EncodableSignature for tx encoding ([#1100](https://github.com/alloy-rs/alloy/issues/1100)) - Eth_simulateV1 Request / Response types ([#1042](https://github.com/alloy-rs/alloy/issues/1042)) @@ -60,6 +92,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- [consensus] Add missing getter trait methods for `alloy_consensus::Transaction` ([#1197](https://github.com/alloy-rs/alloy/issues/1197)) +- Rm Rich type ([#1195](https://github.com/alloy-rs/alloy/issues/1195)) +- Clippy für docs ([#1194](https://github.com/alloy-rs/alloy/issues/1194)) +- Remove RichBlock and RichHeader types ([#1185](https://github.com/alloy-rs/alloy/issues/1185)) +- Add deposit receipt version ([#1188](https://github.com/alloy-rs/alloy/issues/1188)) +- Remove async_trait from NetworkWallet ([#1160](https://github.com/alloy-rs/alloy/issues/1160)) +- JSON-RPC 2.0 spelling ([#1146](https://github.com/alloy-rs/alloy/issues/1146)) +- Add missing 7702 check ([#1137](https://github.com/alloy-rs/alloy/issues/1137)) +- [eip7702] Devnet3 changes ([#1056](https://github.com/alloy-rs/alloy/issues/1056)) +- [dep] Feature gate jwt in engine types ([#1131](https://github.com/alloy-rs/alloy/issues/1131)) - Release 0.2.1 - [rpc] Make `Deserialize` impl for `FilterChanges` generic over transaction ([#1118](https://github.com/alloy-rs/alloy/issues/1118)) - Correctly cfg unused type ([#1117](https://github.com/alloy-rs/alloy/issues/1117)) @@ -75,6 +117,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Other +- Implement conversion between signature types ([#1198](https://github.com/alloy-rs/alloy/issues/1198)) +- Add emhane to codeowners ([#1189](https://github.com/alloy-rs/alloy/issues/1189)) +- Add trait methods for constructing `alloy_rpc_types_eth::Transaction` to `alloy_consensus::Transaction` ([#1172](https://github.com/alloy-rs/alloy/issues/1172)) +- Update TxType comment ([#1175](https://github.com/alloy-rs/alloy/issues/1175)) +- Add payload length methods ([#1152](https://github.com/alloy-rs/alloy/issues/1152)) +- Export types engine default features ([#1143](https://github.com/alloy-rs/alloy/issues/1143)) +- Rm `PeerCount` ([#1140](https://github.com/alloy-rs/alloy/issues/1140)) +- TxRequest into EIP-4844 without sidecar ([#1093](https://github.com/alloy-rs/alloy/issues/1093)) +- Add conversion from BlockHashOrNumber to BlockId ([#1127](https://github.com/alloy-rs/alloy/issues/1127)) +- Make `alloy_rpc_types_eth::SubscriptionResult` generic over tx ([#1123](https://github.com/alloy-rs/alloy/issues/1123)) - Add `AccessListResult` type (EIP-2930) ([#1110](https://github.com/alloy-rs/alloy/issues/1110)) - Derive arbitrary for `TransactionRequest` ([#1113](https://github.com/alloy-rs/alloy/issues/1113)) - Fix typo in genesis ([#1096](https://github.com/alloy-rs/alloy/issues/1096)) @@ -91,6 +143,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Remove proptest in all crates and Arbitrary derives ([#966](https://github.com/alloy-rs/alloy/issues/966)) +### Testing + +- Flaky rpc ([#1180](https://github.com/alloy-rs/alloy/issues/1180)) + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Bug Fixes diff --git a/Cargo.toml b/Cargo.toml index 168c30f194b..db96f817e62 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = ["crates/*"] resolver = "2" [workspace.package] -version = "0.2.1" +version = "0.3.0" edition = "2021" rust-version = "1.76" authors = ["Alloy Contributors"] @@ -35,39 +35,39 @@ all-features = true rustdoc-args = ["--cfg", "docsrs"] [workspace.dependencies] -alloy-consensus = { version = "0.2", path = "crates/consensus", default-features = false } -alloy-contract = { version = "0.2", path = "crates/contract", default-features = false } -alloy-eips = { version = "0.2", path = "crates/eips", default-features = false } -alloy-eip7547 = { version = "0.2", path = "crates/eip7547", default-features = false } -alloy-genesis = { version = "0.2", path = "crates/genesis", default-features = false } -alloy-json-rpc = { version = "0.2", path = "crates/json-rpc", default-features = false } -alloy-network = { version = "0.2", path = "crates/network", default-features = false } -alloy-network-primitives = { version = "0.2", path = "crates/network-primitives", default-features = false } -alloy-node-bindings = { version = "0.2", path = "crates/node-bindings", default-features = false } -alloy-provider = { version = "0.2", path = "crates/provider", default-features = false } -alloy-pubsub = { version = "0.2", path = "crates/pubsub", default-features = false } -alloy-rpc-client = { version = "0.2", path = "crates/rpc-client", default-features = false } -alloy-rpc-types-admin = { version = "0.2", path = "crates/rpc-types-admin", default-features = false } -alloy-rpc-types-anvil = { version = "0.2", path = "crates/rpc-types-anvil", default-features = false } -alloy-rpc-types-beacon = { version = "0.2", path = "crates/rpc-types-beacon", default-features = false } -alloy-rpc-types-debug = { version = "0.2", path = "crates/rpc-types-debug", default-features = false } -alloy-rpc-types-engine = { version = "0.2", path = "crates/rpc-types-engine", default-features = false } -alloy-rpc-types-eth = { version = "0.2", path = "crates/rpc-types-eth", default-features = false } -alloy-rpc-types-mev = { version = "0.2", path = "crates/rpc-types-mev", default-features = false } -alloy-rpc-types-trace = { version = "0.2", path = "crates/rpc-types-trace", default-features = false } -alloy-rpc-types-txpool = { version = "0.2", path = "crates/rpc-types-txpool", default-features = false } -alloy-rpc-types = { version = "0.2", path = "crates/rpc-types", default-features = false } -alloy-serde = { version = "0.2", path = "crates/serde", default-features = false } -alloy-signer = { version = "0.2", path = "crates/signer", default-features = false } -alloy-signer-aws = { version = "0.2", path = "crates/signer-aws", default-features = false } -alloy-signer-gcp = { version = "0.2", path = "crates/signer-gcp", default-features = false } -alloy-signer-ledger = { version = "0.2", path = "crates/signer-ledger", default-features = false } -alloy-signer-local = { version = "0.2", path = "crates/signer-local", default-features = false } -alloy-signer-trezor = { version = "0.2", path = "crates/signer-trezor", default-features = false } -alloy-transport = { version = "0.2", path = "crates/transport", default-features = false } -alloy-transport-http = { version = "0.2", path = "crates/transport-http", default-features = false } -alloy-transport-ipc = { version = "0.2", path = "crates/transport-ipc", default-features = false } -alloy-transport-ws = { version = "0.2", path = "crates/transport-ws", default-features = false } +alloy-consensus = { version = "0.3", path = "crates/consensus", default-features = false } +alloy-contract = { version = "0.3", path = "crates/contract", default-features = false } +alloy-eips = { version = "0.3", path = "crates/eips", default-features = false } +alloy-eip7547 = { version = "0.3", path = "crates/eip7547", default-features = false } +alloy-genesis = { version = "0.3", path = "crates/genesis", default-features = false } +alloy-json-rpc = { version = "0.3", path = "crates/json-rpc", default-features = false } +alloy-network = { version = "0.3", path = "crates/network", default-features = false } +alloy-network-primitives = { version = "0.3", path = "crates/network-primitives", default-features = false } +alloy-node-bindings = { version = "0.3", path = "crates/node-bindings", default-features = false } +alloy-provider = { version = "0.3", path = "crates/provider", default-features = false } +alloy-pubsub = { version = "0.3", path = "crates/pubsub", default-features = false } +alloy-rpc-client = { version = "0.3", path = "crates/rpc-client", default-features = false } +alloy-rpc-types-admin = { version = "0.3", path = "crates/rpc-types-admin", default-features = false } +alloy-rpc-types-anvil = { version = "0.3", path = "crates/rpc-types-anvil", default-features = false } +alloy-rpc-types-beacon = { version = "0.3", path = "crates/rpc-types-beacon", default-features = false } +alloy-rpc-types-debug = { version = "0.3", path = "crates/rpc-types-debug", default-features = false } +alloy-rpc-types-engine = { version = "0.3", path = "crates/rpc-types-engine", default-features = false } +alloy-rpc-types-eth = { version = "0.3", path = "crates/rpc-types-eth", default-features = false } +alloy-rpc-types-mev = { version = "0.3", path = "crates/rpc-types-mev", default-features = false } +alloy-rpc-types-trace = { version = "0.3", path = "crates/rpc-types-trace", default-features = false } +alloy-rpc-types-txpool = { version = "0.3", path = "crates/rpc-types-txpool", default-features = false } +alloy-rpc-types = { version = "0.3", path = "crates/rpc-types", default-features = false } +alloy-serde = { version = "0.3", path = "crates/serde", default-features = false } +alloy-signer = { version = "0.3", path = "crates/signer", default-features = false } +alloy-signer-aws = { version = "0.3", path = "crates/signer-aws", default-features = false } +alloy-signer-gcp = { version = "0.3", path = "crates/signer-gcp", default-features = false } +alloy-signer-ledger = { version = "0.3", path = "crates/signer-ledger", default-features = false } +alloy-signer-local = { version = "0.3", path = "crates/signer-local", default-features = false } +alloy-signer-trezor = { version = "0.3", path = "crates/signer-trezor", default-features = false } +alloy-transport = { version = "0.3", path = "crates/transport", default-features = false } +alloy-transport-http = { version = "0.3", path = "crates/transport-http", default-features = false } +alloy-transport-ipc = { version = "0.3", path = "crates/transport-ipc", default-features = false } +alloy-transport-ws = { version = "0.3", path = "crates/transport-ws", default-features = false } alloy-core = { version = "0.8.0", default-features = false } alloy-dyn-abi = { version = "0.8.0", default-features = false } diff --git a/crates/alloy/CHANGELOG.md b/crates/alloy/CHANGELOG.md index 2b4a653a6e8..fa1baa5a7cf 100644 --- a/crates/alloy/CHANGELOG.md +++ b/crates/alloy/CHANGELOG.md @@ -5,7 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 + +### Dependencies + +- Rm 2930 and 7702 - use alloy-rs/eips ([#1181](https://github.com/alloy-rs/alloy/issues/1181)) +- Bump core and rm ssz feat ([#1167](https://github.com/alloy-rs/alloy/issues/1167)) ### Features diff --git a/crates/consensus/CHANGELOG.md b/crates/consensus/CHANGELOG.md index ac3840c789d..f01dac1bf4d 100644 --- a/crates/consensus/CHANGELOG.md +++ b/crates/consensus/CHANGELOG.md @@ -5,10 +5,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 + +### Dependencies + +- Rm 2930 and 7702 - use alloy-rs/eips ([#1181](https://github.com/alloy-rs/alloy/issues/1181)) ### Features +- Make signature methods generic over EncodableSignature ([#1138](https://github.com/alloy-rs/alloy/issues/1138)) +- Add 7702 tx enum ([#1059](https://github.com/alloy-rs/alloy/issues/1059)) - Use EncodableSignature for tx encoding ([#1100](https://github.com/alloy-rs/alloy/issues/1100)) - [consensus] Add `From` for `Request` ([#1083](https://github.com/alloy-rs/alloy/issues/1083)) - Expose encoded_len_with_signature() ([#1063](https://github.com/alloy-rs/alloy/issues/1063)) @@ -17,11 +23,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- [consensus] Add missing getter trait methods for `alloy_consensus::Transaction` ([#1197](https://github.com/alloy-rs/alloy/issues/1197)) +- Release 0.2.1 - Chore : fix typos ([#1087](https://github.com/alloy-rs/alloy/issues/1087)) - Release 0.2.0 ### Other +- Add trait methods for constructing `alloy_rpc_types_eth::Transaction` to `alloy_consensus::Transaction` ([#1172](https://github.com/alloy-rs/alloy/issues/1172)) +- Update TxType comment ([#1175](https://github.com/alloy-rs/alloy/issues/1175)) +- Add payload length methods ([#1152](https://github.com/alloy-rs/alloy/issues/1152)) - `alloy-consensus` should use `alloy_primitives::Sealable` ([#1072](https://github.com/alloy-rs/alloy/issues/1072)) ### Styling diff --git a/crates/contract/CHANGELOG.md b/crates/contract/CHANGELOG.md index 9dc353d0561..7ba37b6787a 100644 --- a/crates/contract/CHANGELOG.md +++ b/crates/contract/CHANGELOG.md @@ -5,7 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 + +### Bug Fixes + +- Return more user-friendly error on tx timeout ([#1145](https://github.com/alloy-rs/alloy/issues/1145)) ### Miscellaneous Tasks diff --git a/crates/eip7547/CHANGELOG.md b/crates/eip7547/CHANGELOG.md index 9e0795538dd..8470fd51c5b 100644 --- a/crates/eip7547/CHANGELOG.md +++ b/crates/eip7547/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Miscellaneous Tasks diff --git a/crates/eips/CHANGELOG.md b/crates/eips/CHANGELOG.md index a5424f88e7a..e4809481e77 100644 --- a/crates/eips/CHANGELOG.md +++ b/crates/eips/CHANGELOG.md @@ -5,16 +5,23 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Bug Fixes +- [doc] Correct order of fields ([#1139](https://github.com/alloy-rs/alloy/issues/1139)) - Correctly trim eip7251 bytecode ([#1105](https://github.com/alloy-rs/alloy/issues/1105)) - [eips] Make SignedAuthorizationList arbitrary less fallible ([#1084](https://github.com/alloy-rs/alloy/issues/1084)) - Require storageKeys value broken bincode serialization from [#955](https://github.com/alloy-rs/alloy/issues/955) ([#1058](https://github.com/alloy-rs/alloy/issues/1058)) - Cargo fmt ([#1044](https://github.com/alloy-rs/alloy/issues/1044)) - [eip7702] Add correct rlp decode/encode ([#1034](https://github.com/alloy-rs/alloy/issues/1034)) +### Dependencies + +- Rm 2930 and 7702 - use alloy-rs/eips ([#1181](https://github.com/alloy-rs/alloy/issues/1181)) +- Bump core and rm ssz feat ([#1167](https://github.com/alloy-rs/alloy/issues/1167)) +- [deps] Bump some deps ([#1141](https://github.com/alloy-rs/alloy/issues/1141)) + ### Features - [eip] Make 7702 auth recovery fallible ([#1082](https://github.com/alloy-rs/alloy/issues/1082)) @@ -25,11 +32,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Clippy für docs ([#1194](https://github.com/alloy-rs/alloy/issues/1194)) +- [eip7702] Devnet3 changes ([#1056](https://github.com/alloy-rs/alloy/issues/1056)) +- Release 0.2.1 - Release 0.2.0 - Make auth mandatory in recovered auth ([#1047](https://github.com/alloy-rs/alloy/issues/1047)) ### Other +- Add conversion from BlockHashOrNumber to BlockId ([#1127](https://github.com/alloy-rs/alloy/issues/1127)) - Add `AccessListResult` type (EIP-2930) ([#1110](https://github.com/alloy-rs/alloy/issues/1110)) ### Styling diff --git a/crates/genesis/CHANGELOG.md b/crates/genesis/CHANGELOG.md index 2a74f64d576..386ed653940 100644 --- a/crates/genesis/CHANGELOG.md +++ b/crates/genesis/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Features @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Clippy für docs ([#1194](https://github.com/alloy-rs/alloy/issues/1194)) - Release 0.2.1 - Release 0.2.0 diff --git a/crates/json-rpc/CHANGELOG.md b/crates/json-rpc/CHANGELOG.md index cb5d37d600d..4f4ab9ac606 100644 --- a/crates/json-rpc/CHANGELOG.md +++ b/crates/json-rpc/CHANGELOG.md @@ -5,7 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 + +### Bug Fixes + +- Allow arbitrary strings in subscription ids ([#1163](https://github.com/alloy-rs/alloy/issues/1163)) +- [rpc] Show data in when cast send result in custom error ([#1129](https://github.com/alloy-rs/alloy/issues/1129)) ### Features @@ -14,6 +19,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Clippy für docs ([#1194](https://github.com/alloy-rs/alloy/issues/1194)) +- JSON-RPC 2.0 spelling ([#1146](https://github.com/alloy-rs/alloy/issues/1146)) +- Release 0.2.1 - Release 0.2.0 ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 diff --git a/crates/network-primitives/CHANGELOG.md b/crates/network-primitives/CHANGELOG.md index 11ab247977c..0d14783e8d8 100644 --- a/crates/network-primitives/CHANGELOG.md +++ b/crates/network-primitives/CHANGELOG.md @@ -5,7 +5,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 + +### Bug Fixes + +- Make `Block::hash` required ([#1205](https://github.com/alloy-rs/alloy/issues/1205)) + +### Features + +- Network-parameterized block responses ([#1106](https://github.com/alloy-rs/alloy/issues/1106)) ### Miscellaneous Tasks diff --git a/crates/network/CHANGELOG.md b/crates/network/CHANGELOG.md index ef0ed84f3b7..6b2f0a26b90 100644 --- a/crates/network/CHANGELOG.md +++ b/crates/network/CHANGELOG.md @@ -5,10 +5,23 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 + +### Bug Fixes + +- Make `Block::hash` required ([#1205](https://github.com/alloy-rs/alloy/issues/1205)) +- Change generics order for `Block` ([#1192](https://github.com/alloy-rs/alloy/issues/1192)) + +### Features + +- Make block struct generic over header type ([#1179](https://github.com/alloy-rs/alloy/issues/1179)) +- Network-parameterized block responses ([#1106](https://github.com/alloy-rs/alloy/issues/1106)) +- Add 7702 tx enum ([#1059](https://github.com/alloy-rs/alloy/issues/1059)) ### Miscellaneous Tasks +- Remove async_trait from NetworkWallet ([#1160](https://github.com/alloy-rs/alloy/issues/1160)) +- Add missing 7702 check ([#1137](https://github.com/alloy-rs/alloy/issues/1137)) - Release 0.2.1 - Re-export and document network-primitives ([#1107](https://github.com/alloy-rs/alloy/issues/1107)) - Release 0.2.0 diff --git a/crates/node-bindings/CHANGELOG.md b/crates/node-bindings/CHANGELOG.md index c62c5f6322b..af9777df71a 100644 --- a/crates/node-bindings/CHANGELOG.md +++ b/crates/node-bindings/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Bug Fixes @@ -18,6 +18,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Release 0.2.1 - Release 0.2.0 +### Testing + +- Flaky rpc ([#1180](https://github.com/alloy-rs/alloy/issues/1180)) + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Miscellaneous Tasks diff --git a/crates/provider/CHANGELOG.md b/crates/provider/CHANGELOG.md index 7ee14d13b7c..e04f483c42e 100644 --- a/crates/provider/CHANGELOG.md +++ b/crates/provider/CHANGELOG.md @@ -5,20 +5,36 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Bug Fixes +- Make `Block::hash` required ([#1205](https://github.com/alloy-rs/alloy/issues/1205)) +- [provider] Serialize no parameters as `[]` instead of `null` ([#1193](https://github.com/alloy-rs/alloy/issues/1193)) +- Use `server_id` when unsubscribing ([#1182](https://github.com/alloy-rs/alloy/issues/1182)) +- Return more user-friendly error on tx timeout ([#1145](https://github.com/alloy-rs/alloy/issues/1145)) +- Use `BlockId` superset over `BlockNumberOrTag` where applicable ([#1135](https://github.com/alloy-rs/alloy/issues/1135)) - [provider] Prevent panic from having 0 keys when calling `on_anvil_with_wallet_and_config` ([#1055](https://github.com/alloy-rs/alloy/issues/1055)) - [provider] Do not overflow LRU cache capacity in ChainStreamPoller ([#1052](https://github.com/alloy-rs/alloy/issues/1052)) - [admin] Id in NodeInfo is string instead of B256 ([#1038](https://github.com/alloy-rs/alloy/issues/1038)) +### Dependencies + +- [deps] Bump some deps ([#1141](https://github.com/alloy-rs/alloy/issues/1141)) +- Revert "chore(deps): bump some deps" +- [deps] Bump some deps + ### Features +- Add erc4337 endpoint methods to provider ([#1176](https://github.com/alloy-rs/alloy/issues/1176)) +- Add block and transaction generics to otterscan and txpool types ([#1183](https://github.com/alloy-rs/alloy/issues/1183)) +- Network-parameterized block responses ([#1106](https://github.com/alloy-rs/alloy/issues/1106)) +- Add get raw transaction by hash ([#1168](https://github.com/alloy-rs/alloy/issues/1168)) - Add rpc namespace ([#994](https://github.com/alloy-rs/alloy/issues/994)) ### Miscellaneous Tasks +- Clippy für docs ([#1194](https://github.com/alloy-rs/alloy/issues/1194)) - Release 0.2.1 - Correctly cfg unused type ([#1117](https://github.com/alloy-rs/alloy/issues/1117)) - Release 0.2.0 diff --git a/crates/pubsub/CHANGELOG.md b/crates/pubsub/CHANGELOG.md index 2449052513e..03ca72542be 100644 --- a/crates/pubsub/CHANGELOG.md +++ b/crates/pubsub/CHANGELOG.md @@ -5,7 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 + +### Bug Fixes + +- Use `server_id` when unsubscribing ([#1182](https://github.com/alloy-rs/alloy/issues/1182)) +- Allow arbitrary strings in subscription ids ([#1163](https://github.com/alloy-rs/alloy/issues/1163)) ### Miscellaneous Tasks diff --git a/crates/rpc-client/CHANGELOG.md b/crates/rpc-client/CHANGELOG.md index f645b508cf3..89b7a87a07f 100644 --- a/crates/rpc-client/CHANGELOG.md +++ b/crates/rpc-client/CHANGELOG.md @@ -5,7 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 + +### Bug Fixes + +- [provider] Serialize no parameters as `[]` instead of `null` ([#1193](https://github.com/alloy-rs/alloy/issues/1193)) +- Use `server_id` when unsubscribing ([#1182](https://github.com/alloy-rs/alloy/issues/1182)) +- Use `BlockId` superset over `BlockNumberOrTag` where applicable ([#1135](https://github.com/alloy-rs/alloy/issues/1135)) ### Features diff --git a/crates/rpc-types-admin/CHANGELOG.md b/crates/rpc-types-admin/CHANGELOG.md index 860dc7b9388..702b420443c 100644 --- a/crates/rpc-types-admin/CHANGELOG.md +++ b/crates/rpc-types-admin/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Bug Fixes diff --git a/crates/rpc-types-anvil/CHANGELOG.md b/crates/rpc-types-anvil/CHANGELOG.md index 85acc1f683f..71d302cfd9f 100644 --- a/crates/rpc-types-anvil/CHANGELOG.md +++ b/crates/rpc-types-anvil/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Miscellaneous Tasks diff --git a/crates/rpc-types-beacon/CHANGELOG.md b/crates/rpc-types-beacon/CHANGELOG.md index 578219cf9d4..97b7d615fe0 100644 --- a/crates/rpc-types-beacon/CHANGELOG.md +++ b/crates/rpc-types-beacon/CHANGELOG.md @@ -5,10 +5,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 + +### Bug Fixes + +- Remove optimism-related types ([#1203](https://github.com/alloy-rs/alloy/issues/1203)) + +### Dependencies + +- Bump core and rm ssz feat ([#1167](https://github.com/alloy-rs/alloy/issues/1167)) ### Miscellaneous Tasks +- Clippy für docs ([#1194](https://github.com/alloy-rs/alloy/issues/1194)) - Release 0.2.1 - Release 0.2.0 diff --git a/crates/rpc-types-debug/CHANGELOG.md b/crates/rpc-types-debug/CHANGELOG.md index 9e0e2bb287b..38460702304 100644 --- a/crates/rpc-types-debug/CHANGELOG.md +++ b/crates/rpc-types-debug/CHANGELOG.md @@ -4,3 +4,72 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 + +### Features + +- [rpc-types] `debug_executionWitness` ([#1178](https://github.com/alloy-rs/alloy/issues/1178)) + +[`alloy`]: https://crates.io/crates/alloy +[alloy]: https://crates.io/crates/alloy +[`alloy-core`]: https://crates.io/crates/alloy-core +[alloy-core]: https://crates.io/crates/alloy-core +[`alloy-consensus`]: https://crates.io/crates/alloy-consensus +[alloy-consensus]: https://crates.io/crates/alloy-consensus +[`alloy-contract`]: https://crates.io/crates/alloy-contract +[alloy-contract]: https://crates.io/crates/alloy-contract +[`alloy-eips`]: https://crates.io/crates/alloy-eips +[alloy-eips]: https://crates.io/crates/alloy-eips +[`alloy-genesis`]: https://crates.io/crates/alloy-genesis +[alloy-genesis]: https://crates.io/crates/alloy-genesis +[`alloy-json-rpc`]: https://crates.io/crates/alloy-json-rpc +[alloy-json-rpc]: https://crates.io/crates/alloy-json-rpc +[`alloy-network`]: https://crates.io/crates/alloy-network +[alloy-network]: https://crates.io/crates/alloy-network +[`alloy-node-bindings`]: https://crates.io/crates/alloy-node-bindings +[alloy-node-bindings]: https://crates.io/crates/alloy-node-bindings +[`alloy-provider`]: https://crates.io/crates/alloy-provider +[alloy-provider]: https://crates.io/crates/alloy-provider +[`alloy-pubsub`]: https://crates.io/crates/alloy-pubsub +[alloy-pubsub]: https://crates.io/crates/alloy-pubsub +[`alloy-rpc-client`]: https://crates.io/crates/alloy-rpc-client +[alloy-rpc-client]: https://crates.io/crates/alloy-rpc-client +[`alloy-rpc-types`]: https://crates.io/crates/alloy-rpc-types +[alloy-rpc-types]: https://crates.io/crates/alloy-rpc-types +[`alloy-rpc-types-anvil`]: https://crates.io/crates/alloy-rpc-types-anvil +[alloy-rpc-types-anvil]: https://crates.io/crates/alloy-rpc-types-anvil +[`alloy-rpc-types-beacon`]: https://crates.io/crates/alloy-rpc-types-beacon +[alloy-rpc-types-beacon]: https://crates.io/crates/alloy-rpc-types-beacon +[`alloy-rpc-types-engine`]: https://crates.io/crates/alloy-rpc-types-engine +[alloy-rpc-types-engine]: https://crates.io/crates/alloy-rpc-types-engine +[`alloy-rpc-types-eth`]: https://crates.io/crates/alloy-rpc-types-eth +[alloy-rpc-types-eth]: https://crates.io/crates/alloy-rpc-types-eth +[`alloy-rpc-types-trace`]: https://crates.io/crates/alloy-rpc-types-trace +[alloy-rpc-types-trace]: https://crates.io/crates/alloy-rpc-types-trace +[`alloy-serde`]: https://crates.io/crates/alloy-serde +[alloy-serde]: https://crates.io/crates/alloy-serde +[`alloy-signer`]: https://crates.io/crates/alloy-signer +[alloy-signer]: https://crates.io/crates/alloy-signer +[`alloy-signer-aws`]: https://crates.io/crates/alloy-signer-aws +[alloy-signer-aws]: https://crates.io/crates/alloy-signer-aws +[`alloy-signer-gcp`]: https://crates.io/crates/alloy-signer-gcp +[alloy-signer-gcp]: https://crates.io/crates/alloy-signer-gcp +[`alloy-signer-ledger`]: https://crates.io/crates/alloy-signer-ledger +[alloy-signer-ledger]: https://crates.io/crates/alloy-signer-ledger +[`alloy-signer-local`]: https://crates.io/crates/alloy-signer-local +[alloy-signer-local]: https://crates.io/crates/alloy-signer-local +[`alloy-signer-trezor`]: https://crates.io/crates/alloy-signer-trezor +[alloy-signer-trezor]: https://crates.io/crates/alloy-signer-trezor +[`alloy-signer-wallet`]: https://crates.io/crates/alloy-signer-wallet +[alloy-signer-wallet]: https://crates.io/crates/alloy-signer-wallet +[`alloy-transport`]: https://crates.io/crates/alloy-transport +[alloy-transport]: https://crates.io/crates/alloy-transport +[`alloy-transport-http`]: https://crates.io/crates/alloy-transport-http +[alloy-transport-http]: https://crates.io/crates/alloy-transport-http +[`alloy-transport-ipc`]: https://crates.io/crates/alloy-transport-ipc +[alloy-transport-ipc]: https://crates.io/crates/alloy-transport-ipc +[`alloy-transport-ws`]: https://crates.io/crates/alloy-transport-ws +[alloy-transport-ws]: https://crates.io/crates/alloy-transport-ws + + diff --git a/crates/rpc-types-engine/CHANGELOG.md b/crates/rpc-types-engine/CHANGELOG.md index d7b2b80c814..883cef7d143 100644 --- a/crates/rpc-types-engine/CHANGELOG.md +++ b/crates/rpc-types-engine/CHANGELOG.md @@ -5,18 +5,26 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 + +### Bug Fixes + +- Remove optimism-related types ([#1203](https://github.com/alloy-rs/alloy/issues/1203)) ### Dependencies +- Bump core and rm ssz feat ([#1167](https://github.com/alloy-rs/alloy/issues/1167)) - Bump jsonrpsee 0.24 ([#1067](https://github.com/alloy-rs/alloy/issues/1067)) ### Features +- Add error for pre prague requests ([#1204](https://github.com/alloy-rs/alloy/issues/1204)) - [engine-types] `PayloadError::PrePragueBlockWithEip7702Transactions` ([#1116](https://github.com/alloy-rs/alloy/issues/1116)) ### Miscellaneous Tasks +- Clippy für docs ([#1194](https://github.com/alloy-rs/alloy/issues/1194)) +- [dep] Feature gate jwt in engine types ([#1131](https://github.com/alloy-rs/alloy/issues/1131)) - Release 0.2.1 - Release 0.2.0 - Add payloadbodies v2 to capabilities set ([#1025](https://github.com/alloy-rs/alloy/issues/1025)) diff --git a/crates/rpc-types-eth/CHANGELOG.md b/crates/rpc-types-eth/CHANGELOG.md index 79ffa4ceb88..1075abc6343 100644 --- a/crates/rpc-types-eth/CHANGELOG.md +++ b/crates/rpc-types-eth/CHANGELOG.md @@ -5,26 +5,46 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Bug Fixes +- Make `Block::hash` required ([#1205](https://github.com/alloy-rs/alloy/issues/1205)) +- Remove optimism-related types ([#1203](https://github.com/alloy-rs/alloy/issues/1203)) +- Use `impl From for FilterBlockOption` instead of `Range` ([#1199](https://github.com/alloy-rs/alloy/issues/1199)) +- Serde for `depositReceiptVersion` ([#1196](https://github.com/alloy-rs/alloy/issues/1196)) +- Change generics order for `Block` ([#1192](https://github.com/alloy-rs/alloy/issues/1192)) +- Add missing op fields ([#1187](https://github.com/alloy-rs/alloy/issues/1187)) +- Remove `OtherFields` from Transaction and Block ([#1154](https://github.com/alloy-rs/alloy/issues/1154)) +- [rpc-types-eth] Match 7702 in TxReceipt.status() ([#1149](https://github.com/alloy-rs/alloy/issues/1149)) - Trim conflicting key `max_fee_per_blob_gas` from Eip1559 tx type ([#1064](https://github.com/alloy-rs/alloy/issues/1064)) ### Dependencies +- Rm 2930 and 7702 - use alloy-rs/eips ([#1181](https://github.com/alloy-rs/alloy/issues/1181)) +- Bump core and rm ssz feat ([#1167](https://github.com/alloy-rs/alloy/issues/1167)) - Bump jsonrpsee 0.24 ([#1067](https://github.com/alloy-rs/alloy/issues/1067)) ### Features +- Add erc4337 endpoint methods to provider ([#1176](https://github.com/alloy-rs/alloy/issues/1176)) +- Make block struct generic over header type ([#1179](https://github.com/alloy-rs/alloy/issues/1179)) +- Network-parameterized block responses ([#1106](https://github.com/alloy-rs/alloy/issues/1106)) +- Add 7702 tx enum ([#1059](https://github.com/alloy-rs/alloy/issues/1059)) +- Add authorization list to TransactionRequest ([#1125](https://github.com/alloy-rs/alloy/issues/1125)) - Eth_simulateV1 Request / Response types ([#1042](https://github.com/alloy-rs/alloy/issues/1042)) - Feat(rpc-type-eth) convert vec TxReq to bundle ([#1091](https://github.com/alloy-rs/alloy/issues/1091)) -- Feat(provider) : introduction to eth_sendRawTransactionConditional RPC endpoint type ([#1009](https://github.com/alloy-rs/alloy/issues/1009)) +- Feat(provider) : introduction to eth_sendRawTransactionConditional RPC endpoint type ([#1009](https://github.com/alloy-rs/alloy/issues/1009)) - [rpc-types-eth] Serde flatten `BlobTransactionSidecar` in tx req ([#1054](https://github.com/alloy-rs/alloy/issues/1054)) - Add authorization list to rpc transaction and tx receipt types ([#1051](https://github.com/alloy-rs/alloy/issues/1051)) ### Miscellaneous Tasks +- Rm Rich type ([#1195](https://github.com/alloy-rs/alloy/issues/1195)) +- Clippy für docs ([#1194](https://github.com/alloy-rs/alloy/issues/1194)) +- Remove RichBlock and RichHeader types ([#1185](https://github.com/alloy-rs/alloy/issues/1185)) +- Add deposit receipt version ([#1188](https://github.com/alloy-rs/alloy/issues/1188)) +- [eip7702] Devnet3 changes ([#1056](https://github.com/alloy-rs/alloy/issues/1056)) - Release 0.2.1 - [rpc] Make `Deserialize` impl for `FilterChanges` generic over transaction ([#1118](https://github.com/alloy-rs/alloy/issues/1118)) - Export rpc account type ([#1075](https://github.com/alloy-rs/alloy/issues/1075)) @@ -33,6 +53,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Other +- Implement conversion between signature types ([#1198](https://github.com/alloy-rs/alloy/issues/1198)) +- Rm `PeerCount` ([#1140](https://github.com/alloy-rs/alloy/issues/1140)) +- TxRequest into EIP-4844 without sidecar ([#1093](https://github.com/alloy-rs/alloy/issues/1093)) +- Make `alloy_rpc_types_eth::SubscriptionResult` generic over tx ([#1123](https://github.com/alloy-rs/alloy/issues/1123)) - Add `AccessListResult` type (EIP-2930) ([#1110](https://github.com/alloy-rs/alloy/issues/1110)) - Derive arbitrary for `TransactionRequest` ([#1113](https://github.com/alloy-rs/alloy/issues/1113)) - Added stages to the sync info rpc type ([#1079](https://github.com/alloy-rs/alloy/issues/1079)) @@ -40,7 +64,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Refactor - Add network-primitives ([#1101](https://github.com/alloy-rs/alloy/issues/1101)) -- Replace `U64` with `u64` ([#1057](https://github.com/alloy-rs/alloy/issues/1057)) +- Replace `U64` with `u64` ([#1057](https://github.com/alloy-rs/alloy/issues/1057)) ### Styling @@ -112,7 +136,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks - Rm unused txtype mod ([#879](https://github.com/alloy-rs/alloy/issues/879)) -- [other] Use type aliases where possible to improve clarity ([#859](https://github.com/alloy-rs/alloy/issues/859)) +- [other] Use type aliases where possible to improve clarity ([#859](https://github.com/alloy-rs/alloy/issues/859)) - [docs] Crate completeness and fix typos ([#861](https://github.com/alloy-rs/alloy/issues/861)) ### Other diff --git a/crates/rpc-types-mev/CHANGELOG.md b/crates/rpc-types-mev/CHANGELOG.md index 46c273218aa..5702f4ac04f 100644 --- a/crates/rpc-types-mev/CHANGELOG.md +++ b/crates/rpc-types-mev/CHANGELOG.md @@ -5,10 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Miscellaneous Tasks +- Clippy für docs ([#1194](https://github.com/alloy-rs/alloy/issues/1194)) - Release 0.2.1 - Chore : fix typos ([#1087](https://github.com/alloy-rs/alloy/issues/1087)) - Release 0.2.0 diff --git a/crates/rpc-types-trace/CHANGELOG.md b/crates/rpc-types-trace/CHANGELOG.md index bb2dea7d1cb..64b3a719899 100644 --- a/crates/rpc-types-trace/CHANGELOG.md +++ b/crates/rpc-types-trace/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Bug Fixes @@ -13,11 +13,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Features +- Add block and transaction generics to otterscan and txpool types ([#1183](https://github.com/alloy-rs/alloy/issues/1183)) +- [geth/trace] Add field log.position ([#1150](https://github.com/alloy-rs/alloy/issues/1150)) - [rpc/trace] Filter matches with trace ([#1090](https://github.com/alloy-rs/alloy/issues/1090)) - [otterscan] Add ots slim block and serialze OperationType to int ([#1043](https://github.com/alloy-rs/alloy/issues/1043)) ### Miscellaneous Tasks +- Rm Rich type ([#1195](https://github.com/alloy-rs/alloy/issues/1195)) +- Clippy für docs ([#1194](https://github.com/alloy-rs/alloy/issues/1194)) - Release 0.2.1 - Chore : fix typos ([#1087](https://github.com/alloy-rs/alloy/issues/1087)) - Release 0.2.0 diff --git a/crates/rpc-types-txpool/CHANGELOG.md b/crates/rpc-types-txpool/CHANGELOG.md index 323beaef1a5..b0bec33dba3 100644 --- a/crates/rpc-types-txpool/CHANGELOG.md +++ b/crates/rpc-types-txpool/CHANGELOG.md @@ -5,7 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 + +### Features + +- Add block and transaction generics to otterscan and txpool types ([#1183](https://github.com/alloy-rs/alloy/issues/1183)) ### Miscellaneous Tasks diff --git a/crates/rpc-types/CHANGELOG.md b/crates/rpc-types/CHANGELOG.md index 5e26c7bbc87..8e3d2fb66f9 100644 --- a/crates/rpc-types/CHANGELOG.md +++ b/crates/rpc-types/CHANGELOG.md @@ -5,10 +5,15 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 + +### Dependencies + +- Bump core and rm ssz feat ([#1167](https://github.com/alloy-rs/alloy/issues/1167)) ### Features +- [rpc-types] `debug_executionWitness` ([#1178](https://github.com/alloy-rs/alloy/issues/1178)) - Add rpc namespace ([#994](https://github.com/alloy-rs/alloy/issues/994)) ### Miscellaneous Tasks @@ -16,6 +21,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Release 0.2.1 - Release 0.2.0 +### Other + +- Export types engine default features ([#1143](https://github.com/alloy-rs/alloy/issues/1143)) + ## [0.1.4](https://github.com/alloy-rs/alloy/releases/tag/v0.1.4) - 2024-07-08 ### Miscellaneous Tasks diff --git a/crates/serde/CHANGELOG.md b/crates/serde/CHANGELOG.md index 13c026688e5..675bfabadf8 100644 --- a/crates/serde/CHANGELOG.md +++ b/crates/serde/CHANGELOG.md @@ -5,10 +5,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Miscellaneous Tasks +- Release 0.2.1 - Release 0.2.0 - Fix unnameable types ([#1029](https://github.com/alloy-rs/alloy/issues/1029)) diff --git a/crates/signer-aws/CHANGELOG.md b/crates/signer-aws/CHANGELOG.md index caba9a2484a..2dade179b6c 100644 --- a/crates/signer-aws/CHANGELOG.md +++ b/crates/signer-aws/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Miscellaneous Tasks diff --git a/crates/signer-gcp/CHANGELOG.md b/crates/signer-gcp/CHANGELOG.md index ecbbe7af20e..ab10ea16025 100644 --- a/crates/signer-gcp/CHANGELOG.md +++ b/crates/signer-gcp/CHANGELOG.md @@ -5,7 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 + +### Dependencies + +- [deps] Bump some deps ([#1141](https://github.com/alloy-rs/alloy/issues/1141)) +- Revert "chore(deps): bump some deps" +- [deps] Bump some deps ### Miscellaneous Tasks diff --git a/crates/signer-ledger/CHANGELOG.md b/crates/signer-ledger/CHANGELOG.md index 9ade16f4cfa..91bf2e9b6ae 100644 --- a/crates/signer-ledger/CHANGELOG.md +++ b/crates/signer-ledger/CHANGELOG.md @@ -5,7 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 + +### Dependencies + +- [deps] Bump some deps ([#1141](https://github.com/alloy-rs/alloy/issues/1141)) +- Revert "chore(deps): bump some deps" +- [deps] Bump some deps ### Miscellaneous Tasks diff --git a/crates/signer-local/CHANGELOG.md b/crates/signer-local/CHANGELOG.md index 1c50597d862..d6ef4068366 100644 --- a/crates/signer-local/CHANGELOG.md +++ b/crates/signer-local/CHANGELOG.md @@ -5,7 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 + +### Dependencies + +- [deps] Bump some deps ([#1141](https://github.com/alloy-rs/alloy/issues/1141)) +- Revert "chore(deps): bump some deps" +- [deps] Bump some deps ### Miscellaneous Tasks diff --git a/crates/signer-trezor/CHANGELOG.md b/crates/signer-trezor/CHANGELOG.md index ee5bd9f5816..d809cce6144 100644 --- a/crates/signer-trezor/CHANGELOG.md +++ b/crates/signer-trezor/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Dependencies diff --git a/crates/signer/CHANGELOG.md b/crates/signer/CHANGELOG.md index 0b51a2e155a..9374ee9beba 100644 --- a/crates/signer/CHANGELOG.md +++ b/crates/signer/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Features diff --git a/crates/transport-http/CHANGELOG.md b/crates/transport-http/CHANGELOG.md index fa45af65000..efa8ea635c3 100644 --- a/crates/transport-http/CHANGELOG.md +++ b/crates/transport-http/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Miscellaneous Tasks diff --git a/crates/transport-ipc/CHANGELOG.md b/crates/transport-ipc/CHANGELOG.md index b28867b1dea..dc4d68fd3c2 100644 --- a/crates/transport-ipc/CHANGELOG.md +++ b/crates/transport-ipc/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Miscellaneous Tasks diff --git a/crates/transport-ws/CHANGELOG.md b/crates/transport-ws/CHANGELOG.md index 2b673021b7d..46c0b325c3d 100644 --- a/crates/transport-ws/CHANGELOG.md +++ b/crates/transport-ws/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Miscellaneous Tasks diff --git a/crates/transport/CHANGELOG.md b/crates/transport/CHANGELOG.md index f9107b3a8e2..baf3c42ce26 100644 --- a/crates/transport/CHANGELOG.md +++ b/crates/transport/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## [0.2.1](https://github.com/alloy-rs/alloy/releases/tag/v0.2.1) - 2024-08-02 +## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Documentation @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Features +- [transport] Retry http errors with 503 status code ([#1164](https://github.com/alloy-rs/alloy/issues/1164)) - Enable more features transitively in meta crate ([#1097](https://github.com/alloy-rs/alloy/issues/1097)) ### Miscellaneous Tasks From f6550c52aabc1902c935c1f740c86c6b15896326 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Wed, 28 Aug 2024 16:57:37 +0400 Subject: [PATCH 115/186] chore(features): enable `consensus` and `network` along with `providers` (#1207) chore(features): enable consensus and network if providers is --- crates/alloy/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/alloy/Cargo.toml b/crates/alloy/Cargo.toml index 542924c6895..cbea4be8d4d 100644 --- a/crates/alloy/Cargo.toml +++ b/crates/alloy/Cargo.toml @@ -131,7 +131,7 @@ network = ["dep:alloy-network"] node-bindings = ["dep:alloy-node-bindings", "alloy-provider?/anvil-node"] # providers -providers = ["dep:alloy-provider", "rpc-client", "transports", "eips"] +providers = ["dep:alloy-provider", "rpc-client", "transports", "eips", "consensus", "network"] provider-http = ["providers", "transport-http"] provider-ws = ["providers", "alloy-provider?/ws", "transport-ws"] provider-ipc = ["providers", "alloy-provider?/ipc", "transport-ipc"] From ec70d9cc4b81eb0d5e336d3ef364a7a92fdb780c Mon Sep 17 00:00:00 2001 From: StackOverflowExcept1on <109800286+StackOverflowExcept1on@users.noreply.github.com> Date: Wed, 28 Aug 2024 23:25:02 +0300 Subject: [PATCH 116/186] feat(alloy-provider): add abstraction for `NonceFiller` behavior (#1108) * feat(alloy-provider): add abstraction for `NonceFiller` behavior * remove Default bound, add #[non_exhaustive] * resolve conversations * remove default generic * fix ci --- crates/provider/src/builder.rs | 29 ++++- crates/provider/src/fillers/gas.rs | 6 +- crates/provider/src/fillers/mod.rs | 2 +- crates/provider/src/fillers/nonce.rs | 159 ++++++++++++++++++--------- 4 files changed, 136 insertions(+), 60 deletions(-) diff --git a/crates/provider/src/builder.rs b/crates/provider/src/builder.rs index 802daae0c84..4eda6628d2f 100644 --- a/crates/provider/src/builder.rs +++ b/crates/provider/src/builder.rs @@ -1,7 +1,7 @@ use crate::{ fillers::{ - ChainIdFiller, FillerControlFlow, GasFiller, JoinFill, NonceFiller, RecommendedFiller, - TxFiller, WalletFiller, + CachedNonceManager, ChainIdFiller, FillerControlFlow, GasFiller, JoinFill, NonceFiller, + NonceManager, RecommendedFiller, SimpleNonceManager, TxFiller, WalletFiller, }, provider::SendableTx, Provider, RootProvider, @@ -144,8 +144,29 @@ impl ProviderBuilder { /// Add nonce management to the stack being built. /// /// See [`NonceFiller`] - pub fn with_nonce_management(self) -> ProviderBuilder, N> { - self.filler(NonceFiller::default()) + pub fn with_nonce_management( + self, + nonce_manager: M, + ) -> ProviderBuilder>, N> { + self.filler(NonceFiller::new(nonce_manager)) + } + + /// Add simple nonce management to the stack being built. + /// + /// See [`SimpleNonceManager`] + pub fn with_simple_nonce_management( + self, + ) -> ProviderBuilder, N> { + self.with_nonce_management(SimpleNonceManager::default()) + } + + /// Add cached nonce management to the stack being built. + /// + /// See [`CachedNonceManager`] + pub fn with_cached_nonce_management( + self, + ) -> ProviderBuilder>, N> { + self.with_nonce_management(CachedNonceManager::default()) } /// Add a chain ID filler to the stack being built. The filler will attempt diff --git a/crates/provider/src/fillers/gas.rs b/crates/provider/src/fillers/gas.rs index 422c750ab0a..1c6c646fbf9 100644 --- a/crates/provider/src/fillers/gas.rs +++ b/crates/provider/src/fillers/gas.rs @@ -303,11 +303,7 @@ mod tests { #[tokio::test] async fn non_eip1559_network() { - let provider = ProviderBuilder::new() - .filler(crate::fillers::GasFiller) - .filler(crate::fillers::NonceFiller::default()) - .filler(crate::fillers::ChainIdFiller::default()) - .on_anvil(); + let provider = ProviderBuilder::new().with_recommended_fillers().on_anvil(); let tx = TransactionRequest { from: Some(address!("f39Fd6e51aad88F6F4ce6aB8827279cffFb92266")), diff --git a/crates/provider/src/fillers/mod.rs b/crates/provider/src/fillers/mod.rs index e2321f45ce0..e487d9f0fe4 100644 --- a/crates/provider/src/fillers/mod.rs +++ b/crates/provider/src/fillers/mod.rs @@ -13,7 +13,7 @@ mod wallet; pub use wallet::WalletFiller; mod nonce; -pub use nonce::NonceFiller; +pub use nonce::{CachedNonceManager, NonceFiller, NonceManager, SimpleNonceManager}; mod gas; pub use gas::{GasFillable, GasFiller}; diff --git a/crates/provider/src/fillers/nonce.rs b/crates/provider/src/fillers/nonce.rs index ad9f0aa60f8..273499bab72 100644 --- a/crates/provider/src/fillers/nonce.rs +++ b/crates/provider/src/fillers/nonce.rs @@ -6,15 +6,90 @@ use crate::{ use alloy_network::{Network, TransactionBuilder}; use alloy_primitives::Address; use alloy_transport::{Transport, TransportResult}; +use async_trait::async_trait; use dashmap::DashMap; use futures::lock::Mutex; use std::sync::Arc; -/// A [`TxFiller`] that fills nonces on transactions. +/// A trait that determines the behavior of filling nonces. +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +pub trait NonceManager: Clone + Send + Sync + std::fmt::Debug { + /// Get the next nonce for the given account. + async fn get_next_nonce(&self, provider: &P, address: Address) -> TransportResult + where + P: Provider, + N: Network, + T: Transport + Clone; +} + +/// This [`NonceManager`] implementation will fetch the transaction count for any new account it +/// sees. +/// +/// Unlike [`CachedNonceManager`], this implementation does not store the transaction count locally, +/// which results in more frequent calls to the provider, but it is more resilient to chain +/// reorganizations. +#[derive(Clone, Debug, Default)] +#[non_exhaustive] +pub struct SimpleNonceManager; + +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +impl NonceManager for SimpleNonceManager { + async fn get_next_nonce(&self, provider: &P, address: Address) -> TransportResult + where + P: Provider, + N: Network, + T: Transport + Clone, + { + provider.get_transaction_count(address).await + } +} + +/// This [`NonceManager`] implementation will fetch the transaction count for any new account it +/// sees, store it locally and increment the locally stored nonce as transactions are sent via +/// [`Provider::send_transaction`]. /// -/// The filler will fetch the transaction count for any new account it sees, -/// store it locally and increment the locally stored nonce as transactions are -/// sent via [`Provider::send_transaction`]. +/// There is also an alternative implementation [`SimpleNonceManager`] that does not store the +/// transaction count locally. +#[derive(Clone, Debug, Default)] +pub struct CachedNonceManager { + nonces: DashMap>>, +} + +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +impl NonceManager for CachedNonceManager { + async fn get_next_nonce(&self, provider: &P, address: Address) -> TransportResult + where + P: Provider, + N: Network, + T: Transport + Clone, + { + // Use `u64::MAX` as a sentinel value to indicate that the nonce has not been fetched yet. + const NONE: u64 = u64::MAX; + + // Locks dashmap internally for a short duration to clone the `Arc`. + // We also don't want to hold the dashmap lock through the await point below. + let nonce = { + let rm = self.nonces.entry(address).or_insert_with(|| Arc::new(Mutex::new(NONE))); + Arc::clone(rm.value()) + }; + + let mut nonce = nonce.lock().await; + let new_nonce = if *nonce == NONE { + // Initialize the nonce if we haven't seen this account before. + provider.get_transaction_count(address).await? + } else { + *nonce + 1 + }; + *nonce = new_nonce; + Ok(new_nonce) + } +} + +/// A [`TxFiller`] that fills nonces on transactions. The behavior of filling nonces is determined +/// by the [`NonceManager`]. /// /// # Note /// @@ -31,7 +106,7 @@ use std::sync::Arc; /// # use alloy_provider::{ProviderBuilder, RootProvider, Provider}; /// # async fn test + Clone>(url: url::Url, wallet: W) -> Result<(), Box> { /// let provider = ProviderBuilder::new() -/// .with_nonce_management() +/// .with_simple_nonce_management() /// .wallet(wallet) /// .on_http(url); /// @@ -40,11 +115,18 @@ use std::sync::Arc; /// # } /// ``` #[derive(Clone, Debug, Default)] -pub struct NonceFiller { - nonces: DashMap>>, +pub struct NonceFiller { + nonce_manager: M, +} + +impl NonceFiller { + /// Creates a new [`NonceFiller`] with the specified [`NonceManager`]. + pub const fn new(nonce_manager: M) -> Self { + Self { nonce_manager } + } } -impl TxFiller for NonceFiller { +impl TxFiller for NonceFiller { type Fillable = u64; fn status(&self, tx: &::TransactionRequest) -> FillerControlFlow { @@ -69,7 +151,7 @@ impl TxFiller for NonceFiller { T: Transport + Clone, { let from = tx.from().expect("checked by 'ready()'"); - self.get_next_nonce(provider, from).await + self.nonce_manager.get_next_nonce(provider, from).await } async fn fill( @@ -84,36 +166,6 @@ impl TxFiller for NonceFiller { } } -impl NonceFiller { - /// Get the next nonce for the given account. - async fn get_next_nonce(&self, provider: &P, address: Address) -> TransportResult - where - P: Provider, - N: Network, - T: Transport + Clone, - { - // Use `u64::MAX` as a sentinel value to indicate that the nonce has not been fetched yet. - const NONE: u64 = u64::MAX; - - // Locks dashmap internally for a short duration to clone the `Arc`. - // We also don't want to hold the dashmap lock through the await point below. - let nonce = { - let rm = self.nonces.entry(address).or_insert_with(|| Arc::new(Mutex::new(NONE))); - Arc::clone(rm.value()) - }; - - let mut nonce = nonce.lock().await; - let new_nonce = if *nonce == NONE { - // Initialize the nonce if we haven't seen this account before. - provider.get_transaction_count(address).await? - } else { - *nonce + 1 - }; - *nonce = new_nonce; - Ok(new_nonce) - } -} - #[cfg(test)] mod tests { use super::*; @@ -121,21 +173,26 @@ mod tests { use alloy_primitives::{address, U256}; use alloy_rpc_types_eth::TransactionRequest; - async fn check_nonces(filler: &NonceFiller, provider: &P, address: Address, start: u64) - where + async fn check_nonces( + filler: &NonceFiller, + provider: &P, + address: Address, + start: u64, + ) where P: Provider, N: Network, T: Transport + Clone, + M: NonceManager, { for i in start..start + 5 { - let nonce = filler.get_next_nonce(&provider, address).await.unwrap(); + let nonce = filler.nonce_manager.get_next_nonce(&provider, address).await.unwrap(); assert_eq!(nonce, i); } } #[tokio::test] async fn smoke_test() { - let filler = NonceFiller::default(); + let filler = NonceFiller::::default(); let provider = ProviderBuilder::new().on_anvil(); let address = Address::ZERO; check_nonces(&filler, &provider, address, 0).await; @@ -143,7 +200,7 @@ mod tests { #[cfg(feature = "anvil-api")] { use crate::ext::AnvilApi; - filler.nonces.clear(); + filler.nonce_manager.nonces.clear(); provider.anvil_set_nonce(address, U256::from(69)).await.unwrap(); check_nonces(&filler, &provider, address, 69).await; } @@ -151,14 +208,16 @@ mod tests { #[tokio::test] async fn concurrency() { - let filler = Arc::new(NonceFiller::default()); + let filler = Arc::new(NonceFiller::::default()); let provider = Arc::new(ProviderBuilder::new().on_anvil()); let address = Address::ZERO; let tasks = (0..5) .map(|_| { let filler = Arc::clone(&filler); let provider = Arc::clone(&provider); - tokio::spawn(async move { filler.get_next_nonce(&provider, address).await }) + tokio::spawn(async move { + filler.nonce_manager.get_next_nonce(&provider, address).await + }) }) .collect::>(); @@ -169,13 +228,13 @@ mod tests { ns.sort_unstable(); assert_eq!(ns, (0..5).collect::>()); - assert_eq!(filler.nonces.len(), 1); - assert_eq!(*filler.nonces.get(&address).unwrap().value().lock().await, 4); + assert_eq!(filler.nonce_manager.nonces.len(), 1); + assert_eq!(*filler.nonce_manager.nonces.get(&address).unwrap().value().lock().await, 4); } #[tokio::test] async fn no_nonce_if_sender_unset() { - let provider = ProviderBuilder::new().with_nonce_management().on_anvil(); + let provider = ProviderBuilder::new().with_cached_nonce_management().on_anvil(); let tx = TransactionRequest { value: Some(U256::from(100)), @@ -191,7 +250,7 @@ mod tests { #[tokio::test] async fn increments_nonce() { - let provider = ProviderBuilder::new().with_nonce_management().on_anvil_with_wallet(); + let provider = ProviderBuilder::new().with_cached_nonce_management().on_anvil_with_wallet(); let from = provider.default_signer_address(); let tx = TransactionRequest { From e30d5108350d421723df4864b927116a13c3d028 Mon Sep 17 00:00:00 2001 From: "Julie B." <15657735+bbjubjub2494@users.noreply.github.com> Date: Thu, 29 Aug 2024 01:56:16 +0200 Subject: [PATCH 117/186] fix: value of TxEip1559.ty (#1210) --- crates/consensus/src/transaction/eip1559.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/consensus/src/transaction/eip1559.rs b/crates/consensus/src/transaction/eip1559.rs index c53d39b3160..3f072cc8a05 100644 --- a/crates/consensus/src/transaction/eip1559.rs +++ b/crates/consensus/src/transaction/eip1559.rs @@ -307,7 +307,7 @@ impl Transaction for TxEip1559 { } fn ty(&self) -> u8 { - TxType::Eip2930 as u8 + TxType::Eip1559 as u8 } fn access_list(&self) -> Option<&AccessList> { From 75f738bd7062830633b51b8575d23411fc78f987 Mon Sep 17 00:00:00 2001 From: MistApproach <98988043+MistApproach@users.noreply.github.com> Date: Thu, 29 Aug 2024 09:19:37 +0200 Subject: [PATCH 118/186] docs: update version (#1211) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e528389819e..c1001e4416f 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ cargo add alloy --features full Alternatively, you can add the following to your `Cargo.toml` file: ```toml -alloy = { version = "0.2", features = ["full"] } +alloy = { version = "0.3", features = ["full"] } ``` For a more fine-grained control over the features you wish to include, you can add the individual crates to your `Cargo.toml` file, or use the `alloy` crate with the features you need. From 2c831b0083e2aad136fa09924f3a2d4a3768c00d Mon Sep 17 00:00:00 2001 From: morito Date: Thu, 29 Aug 2024 16:50:23 +0900 Subject: [PATCH 119/186] chore(README): Add a link to `rpc-types-debug` (#1212) Add a link to roc-types-debug --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c1001e4416f..fd70d7baaf4 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,7 @@ This repository contains the following crates: [`alloy-rpc-types-admin`]: https://github.com/alloy-rs/alloy/tree/main/crates/rpc-types-admin [`alloy-rpc-types-anvil`]: https://github.com/alloy-rs/alloy/tree/main/crates/rpc-types-anvil [`alloy-rpc-types-beacon`]: https://github.com/alloy-rs/alloy/tree/main/crates/rpc-types-beacon +[`alloy-rpc-types-debug`]: https://github.com/alloy-rs/alloy/tree/main/crates/rpc-types-debug [`alloy-rpc-types-engine`]: https://github.com/alloy-rs/alloy/tree/main/crates/rpc-types-engine [`alloy-rpc-types-eth`]: https://github.com/alloy-rs/alloy/tree/main/crates/rpc-types-eth [`alloy-rpc-types-mev`]: https://github.com/alloy-rs/alloy/tree/main/crates/rpc-types-mev From 6f0bfdb3386829a6bb4e5732730f138ddc201353 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Thu, 29 Aug 2024 08:34:18 -0700 Subject: [PATCH 120/186] feat: implement `tx_type` for `TxEip7702` (#1214) eip7702: implement tx_type for TxEip7702 --- crates/consensus/src/transaction/eip7702.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/crates/consensus/src/transaction/eip7702.rs b/crates/consensus/src/transaction/eip7702.rs index c34a0471810..bd667082687 100644 --- a/crates/consensus/src/transaction/eip7702.rs +++ b/crates/consensus/src/transaction/eip7702.rs @@ -250,9 +250,8 @@ impl TxEip7702 { /// Get transaction type #[doc(alias = "transaction_type")] - #[allow(unused)] - pub(crate) fn tx_type(&self) -> TxType { - unimplemented!("not yet added to tx type enum") + pub const fn tx_type(&self) -> TxType { + TxType::Eip7702 } /// Calculates a heuristic for the in-memory size of the [TxEip7702] transaction. From 08c3c346c442a83946c22b0e9cb7484c2abb3719 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Thu, 29 Aug 2024 10:22:21 -0700 Subject: [PATCH 121/186] feat: derive `arbitrary::Arbitrary` for `TxEip7702` (#1216) eip7702: derive arbitrary::Arbitrary for TxEip7702 --- crates/consensus/src/transaction/eip7702.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/consensus/src/transaction/eip7702.rs b/crates/consensus/src/transaction/eip7702.rs index bd667082687..f3b88065cde 100644 --- a/crates/consensus/src/transaction/eip7702.rs +++ b/crates/consensus/src/transaction/eip7702.rs @@ -10,6 +10,7 @@ use alloy_eips::eip7702::{constants::EIP7702_TX_TYPE_ID, SignedAuthorization}; /// A transaction with a priority fee ([EIP-7702](https://eips.ethereum.org/EIPS/eip-7702)). #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +#[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] #[doc(alias = "Eip7702Transaction", alias = "TransactionEip7702", alias = "Eip7702Tx")] From e51ed77010457f378c78bf0a17abe0d7584a09e7 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Fri, 30 Aug 2024 01:18:58 -0700 Subject: [PATCH 122/186] bump rust msrv to 1.78 (#1219) --- .github/workflows/ci.yml | 10 +++++----- Cargo.toml | 2 +- README.md | 2 +- clippy.toml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8e4dee9142c..8a4eff4a4e7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: rust: - "stable" - "nightly" - - "1.76" # MSRV + - "1.78" # MSRV flags: # No features - "--no-default-features" @@ -34,7 +34,7 @@ jobs: - "--all-features" exclude: # All features on MSRV - - rust: "1.76" # MSRV + - rust: "1.78" # MSRV flags: "--all-features" steps: - uses: actions/checkout@v4 @@ -53,14 +53,14 @@ jobs: cache-on-failure: true # Only run tests on latest stable and above - name: Install cargo-nextest - if: ${{ matrix.rust != '1.76' }} # MSRV + if: ${{ matrix.rust != '1.78' }} # MSRV uses: taiki-e/install-action@nextest - name: build - if: ${{ matrix.rust == '1.76' }} # MSRV + if: ${{ matrix.rust == '1.78' }} # MSRV run: cargo build --workspace ${{ matrix.flags }} - name: test shell: bash - if: ${{ matrix.rust != '1.76' }} # MSRV + if: ${{ matrix.rust != '1.78' }} # MSRV run: cargo nextest run --workspace ${{ matrix.flags }} doctest: diff --git a/Cargo.toml b/Cargo.toml index db96f817e62..94fd42d6977 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ resolver = "2" [workspace.package] version = "0.3.0" edition = "2021" -rust-version = "1.76" +rust-version = "1.78" authors = ["Alloy Contributors"] license = "MIT OR Apache-2.0" homepage = "https://github.com/alloy-rs/alloy" diff --git a/README.md b/README.md index fd70d7baaf4..cde535f8cb7 100644 --- a/README.md +++ b/README.md @@ -124,7 +124,7 @@ When updating this, also update: - .github/workflows/ci.yml --> -The current MSRV (minimum supported rust version) is 1.76. +The current MSRV (minimum supported rust version) is 1.78. Alloy will keep a rolling MSRV policy of **at least** two versions behind the latest stable release (so if the latest stable release is 1.58, we would diff --git a/clippy.toml b/clippy.toml index 472818efed9..0c4f17e6aea 100644 --- a/clippy.toml +++ b/clippy.toml @@ -1 +1 @@ -msrv = "1.76" +msrv = "1.78" From bfbbc3246bac830dda96d90e9ab759b979f90bdc Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Fri, 30 Aug 2024 05:50:41 -0700 Subject: [PATCH 123/186] eip7702: rm useless methods for `TxEip7702` (#1221) eip7702: rm useless methods --- crates/consensus/src/transaction/eip7702.rs | 73 +-------------------- 1 file changed, 2 insertions(+), 71 deletions(-) diff --git a/crates/consensus/src/transaction/eip7702.rs b/crates/consensus/src/transaction/eip7702.rs index f3b88065cde..c2e704a4df8 100644 --- a/crates/consensus/src/transaction/eip7702.rs +++ b/crates/consensus/src/transaction/eip7702.rs @@ -1,7 +1,7 @@ use crate::{EncodableSignature, SignableTransaction, Signed, Transaction, TxType}; use alloy_eips::eip2930::AccessList; use alloy_primitives::{keccak256, Bytes, ChainId, Signature, TxKind, B256, U256}; -use alloy_rlp::{length_of_length, BufMut, Decodable, Encodable, Header}; +use alloy_rlp::{BufMut, Decodable, Encodable, Header}; use core::mem; #[cfg(not(feature = "std"))] @@ -269,19 +269,6 @@ impl TxEip7702 { self.input.len() + // input self.authorization_list.capacity() * mem::size_of::() // authorization_list } - - /// Output the length of the RLP signed transaction encoding, _without_ a RLP string header. - pub fn payload_len_with_signature_without_header(&self, signature: &Signature) -> usize { - let payload_length = self.fields_len() + signature.rlp_vrs_len(); - // 'transaction type byte length' + 'header length' + 'payload length' - 1 + length_of_length(payload_length) + payload_length - } - - /// Output the length of the RLP signed transaction encoding. This encodes with a RLP header. - pub fn payload_len_with_signature(&self, signature: &Signature) -> usize { - let len = self.payload_len_with_signature_without_header(signature); - length_of_length(len) + len - } } impl Transaction for TxEip7702 { @@ -401,66 +388,10 @@ impl Decodable for TxEip7702 { #[cfg(all(test, feature = "k256"))] mod tests { - use core::str::FromStr; - use super::TxEip7702; use crate::SignableTransaction; use alloy_eips::eip2930::AccessList; - use alloy_primitives::{address, b256, hex, Address, Bytes, Signature, TxKind, U256}; - - #[test] - fn test_payload_len_with_signature_without_header() { - let tx = TxEip7702 { - chain_id: 1u64, - nonce: 0, - max_fee_per_gas: 0x4a817c800, - max_priority_fee_per_gas: 0x3b9aca00, - gas_limit: 2, - to: TxKind::Create, - value: U256::ZERO, - input: Bytes::from(vec![1, 2]), - access_list: Default::default(), - authorization_list: Default::default(), - }; - - let signature = Signature::from_rs_and_parity( - U256::from_str("0xc569c92f176a3be1a6352dd5005bfc751dcb32f57623dd2a23693e64bf4447b0") - .unwrap(), - U256::from_str("0x1a891b566d369e79b7a66eecab1e008831e22daa15f91a0a0cf4f9f28f47ee05") - .unwrap(), - 1, - ) - .unwrap(); - - assert_eq!(tx.payload_len_with_signature_without_header(&signature), 91); - } - - #[test] - fn test_payload_len_with_signature() { - let tx = TxEip7702 { - chain_id: 1u64, - nonce: 0, - max_fee_per_gas: 0x4a817c800, - max_priority_fee_per_gas: 0x3b9aca00, - gas_limit: 2, - to: TxKind::Create, - value: U256::ZERO, - input: Bytes::from(vec![1, 2]), - access_list: Default::default(), - authorization_list: Default::default(), - }; - - let signature = Signature::from_rs_and_parity( - U256::from_str("0xc569c92f176a3be1a6352dd5005bfc751dcb32f57623dd2a23693e64bf4447b0") - .unwrap(), - U256::from_str("0x1a891b566d369e79b7a66eecab1e008831e22daa15f91a0a0cf4f9f28f47ee05") - .unwrap(), - 1, - ) - .unwrap(); - - assert_eq!(tx.payload_len_with_signature(&signature), 93); - } + use alloy_primitives::{address, b256, hex, Address, Signature, TxKind, U256}; #[test] fn encode_decode_eip7702() { From 24e97da7fa86d6cd49b418a1c89702648c36d36b Mon Sep 17 00:00:00 2001 From: refcell Date: Fri, 30 Aug 2024 18:11:40 -0400 Subject: [PATCH 124/186] fix(eips): no-std compat (#1222) * fix(eips): no-std compat * fix(eips): no-std compat --- crates/eips/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/eips/Cargo.toml b/crates/eips/Cargo.toml index 1e327cd7de9..55dc96a3315 100644 --- a/crates/eips/Cargo.toml +++ b/crates/eips/Cargo.toml @@ -36,7 +36,7 @@ derive_more = { workspace = true, features = [ "as_ref", "deref", "deref_mut", -], optional = true } +], default-features = false, optional = true } once_cell = { workspace = true, features = ["race", "alloc"], optional = true } sha2 = { workspace = true, optional = true } @@ -59,7 +59,7 @@ serde_json.workspace = true [features] default = ["std", "kzg-sidecar"] -std = ["alloy-primitives/std", "alloy-rlp/std", +std = ["alloy-primitives/std", "alloy-rlp/std", "derive_more/std", "serde?/std", "c-kzg?/std", "once_cell?/std"] serde = ["dep:alloy-serde", "dep:serde", "alloy-primitives/serde", "c-kzg?/serde", "alloy-eip2930/serde", "alloy-eip7702/serde"] From 59a39ac832bed3ab7d70895f16378f06587dd4dd Mon Sep 17 00:00:00 2001 From: refcell Date: Sat, 31 Aug 2024 16:24:19 -0400 Subject: [PATCH 125/186] feat: workflow to validate no_std compatibility (#1223) --- .github/workflows/no_std.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/no_std.yml diff --git a/.github/workflows/no_std.yml b/.github/workflows/no_std.yml new file mode 100644 index 00000000000..9d16d58084d --- /dev/null +++ b/.github/workflows/no_std.yml @@ -0,0 +1,25 @@ +name: no_std + +on: + push: + branches: [main] + pull_request: + +env: + CARGO_TERM_COLOR: always + +jobs: + check-no-std: + name: check no_std ${{ matrix.features }} + runs-on: ubuntu-latest + timeout-minutes: 30 + strategy: + fail-fast: false + matrix: + crate: ["alloy-eips", "alloy-consensus", "alloy-genesis"] + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + with: + targets: riscv32imac-unknown-none-elf + - run: cargo check --target riscv32imac-unknown-none-elf --no-default-features -p ${{ matrix.crate }} From 91d323f62dc8f0afa8aa954dd0d8f9ab9501b364 Mon Sep 17 00:00:00 2001 From: MistApproach <98988043+MistApproach@users.noreply.github.com> Date: Sat, 31 Aug 2024 22:55:17 +0200 Subject: [PATCH 126/186] fix: Anvil builder default port (#1213) * fix: Anvil builder default port * revert: Anvil builder default port * docs: update Anvil default port --- crates/node-bindings/src/anvil.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/node-bindings/src/anvil.rs b/crates/node-bindings/src/anvil.rs index 21028610210..0572cf0fdd1 100644 --- a/crates/node-bindings/src/anvil.rs +++ b/crates/node-bindings/src/anvil.rs @@ -164,7 +164,7 @@ pub struct Anvil { impl Anvil { /// Creates an empty Anvil builder. - /// The default port is 8545. The mnemonic is chosen randomly. + /// The default port and the mnemonic are chosen randomly. /// /// # Example /// From 8d5f0652082ac7e1f1b2a1c415af2b7b02832810 Mon Sep 17 00:00:00 2001 From: evalir Date: Mon, 2 Sep 2024 07:22:39 -0400 Subject: [PATCH 127/186] feat(`json-rpc`): implement From U256 and String for SubId (#1226) feat(json-rpc): implement From U256 and String for SubId --- crates/json-rpc/src/notification.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/crates/json-rpc/src/notification.rs b/crates/json-rpc/src/notification.rs index e1af087127b..d6f6a9ab4be 100644 --- a/crates/json-rpc/src/notification.rs +++ b/crates/json-rpc/src/notification.rs @@ -15,6 +15,18 @@ pub enum SubId { String(String), } +impl From for SubId { + fn from(value: U256) -> Self { + Self::Number(value) + } +} + +impl From for SubId { + fn from(value: String) -> Self { + Self::String(value) + } +} + /// An ethereum-style notification, not to be confused with a JSON-RPC /// notification. #[derive(Clone, Debug, Serialize, Deserialize)] From 177f86575211e928fa318760cd5f6314ffc82cf6 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Mon, 2 Sep 2024 15:55:59 +0200 Subject: [PATCH 128/186] chore: release 0.3.1 --- CHANGELOG.md | 34 ++++++++++++++++++++++++++ Cargo.toml | 2 +- crates/alloy/CHANGELOG.md | 7 ++++++ crates/consensus/CHANGELOG.md | 16 ++++++++++++ crates/contract/CHANGELOG.md | 1 + crates/eip7547/CHANGELOG.md | 1 + crates/eips/CHANGELOG.md | 7 ++++++ crates/genesis/CHANGELOG.md | 1 + crates/json-rpc/CHANGELOG.md | 7 ++++++ crates/network-primitives/CHANGELOG.md | 1 + crates/network/CHANGELOG.md | 1 + crates/node-bindings/CHANGELOG.md | 7 ++++++ crates/provider/CHANGELOG.md | 7 ++++++ crates/pubsub/CHANGELOG.md | 1 + crates/rpc-client/CHANGELOG.md | 1 + crates/rpc-types-admin/CHANGELOG.md | 1 + crates/rpc-types-anvil/CHANGELOG.md | 1 + crates/rpc-types-beacon/CHANGELOG.md | 1 + crates/rpc-types-debug/CHANGELOG.md | 4 +++ crates/rpc-types-engine/CHANGELOG.md | 1 + crates/rpc-types-eth/CHANGELOG.md | 1 + crates/rpc-types-mev/CHANGELOG.md | 1 + crates/rpc-types-trace/CHANGELOG.md | 1 + crates/rpc-types-txpool/CHANGELOG.md | 1 + crates/rpc-types/CHANGELOG.md | 1 + crates/serde/CHANGELOG.md | 1 + crates/signer-aws/CHANGELOG.md | 1 + crates/signer-gcp/CHANGELOG.md | 1 + crates/signer-ledger/CHANGELOG.md | 1 + crates/signer-local/CHANGELOG.md | 1 + crates/signer-trezor/CHANGELOG.md | 1 + crates/signer/CHANGELOG.md | 1 + crates/transport-http/CHANGELOG.md | 1 + crates/transport-ipc/CHANGELOG.md | 1 + crates/transport-ws/CHANGELOG.md | 1 + crates/transport/CHANGELOG.md | 1 + 36 files changed, 117 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0492ace7812..fb34b4ccaba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,39 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Bug Fixes + +- Anvil builder default port ([#1213](https://github.com/alloy-rs/alloy/issues/1213)) +- [eips] No-std compat ([#1222](https://github.com/alloy-rs/alloy/issues/1222)) +- Value of TxEip1559.ty ([#1210](https://github.com/alloy-rs/alloy/issues/1210)) + +### Dependencies + +- Bump rust msrv to 1.78 ([#1219](https://github.com/alloy-rs/alloy/issues/1219)) + +### Documentation + +- Update version ([#1211](https://github.com/alloy-rs/alloy/issues/1211)) + +### Features + +- [`json-rpc`] Implement From U256 and String for SubId ([#1226](https://github.com/alloy-rs/alloy/issues/1226)) +- Workflow to validate no_std compatibility ([#1223](https://github.com/alloy-rs/alloy/issues/1223)) +- Derive `arbitrary::Arbitrary` for `TxEip7702` ([#1216](https://github.com/alloy-rs/alloy/issues/1216)) +- Implement `tx_type` for `TxEip7702` ([#1214](https://github.com/alloy-rs/alloy/issues/1214)) +- [alloy-provider] Add abstraction for `NonceFiller` behavior ([#1108](https://github.com/alloy-rs/alloy/issues/1108)) + +### Miscellaneous Tasks + +- [README] Add a link to `rpc-types-debug` ([#1212](https://github.com/alloy-rs/alloy/issues/1212)) +- [features] Enable `consensus` and `network` along with `providers` ([#1207](https://github.com/alloy-rs/alloy/issues/1207)) + +### Other + +- Rm useless methods for `TxEip7702` ([#1221](https://github.com/alloy-rs/alloy/issues/1221)) + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Bug Fixes @@ -92,6 +125,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - [consensus] Add missing getter trait methods for `alloy_consensus::Transaction` ([#1197](https://github.com/alloy-rs/alloy/issues/1197)) - Rm Rich type ([#1195](https://github.com/alloy-rs/alloy/issues/1195)) - Clippy für docs ([#1194](https://github.com/alloy-rs/alloy/issues/1194)) diff --git a/Cargo.toml b/Cargo.toml index 94fd42d6977..f4909ffe980 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = ["crates/*"] resolver = "2" [workspace.package] -version = "0.3.0" +version = "0.3.1" edition = "2021" rust-version = "1.78" authors = ["Alloy Contributors"] diff --git a/crates/alloy/CHANGELOG.md b/crates/alloy/CHANGELOG.md index fa1baa5a7cf..027485de5bb 100644 --- a/crates/alloy/CHANGELOG.md +++ b/crates/alloy/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- [features] Enable `consensus` and `network` along with `providers` ([#1207](https://github.com/alloy-rs/alloy/issues/1207)) + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Dependencies @@ -19,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Release 0.2.1 - Release 0.2.0 diff --git a/crates/consensus/CHANGELOG.md b/crates/consensus/CHANGELOG.md index f01dac1bf4d..2efa49bcac4 100644 --- a/crates/consensus/CHANGELOG.md +++ b/crates/consensus/CHANGELOG.md @@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Bug Fixes + +- Value of TxEip1559.ty ([#1210](https://github.com/alloy-rs/alloy/issues/1210)) + +### Features + +- Derive `arbitrary::Arbitrary` for `TxEip7702` ([#1216](https://github.com/alloy-rs/alloy/issues/1216)) +- Implement `tx_type` for `TxEip7702` ([#1214](https://github.com/alloy-rs/alloy/issues/1214)) + +### Other + +- Rm useless methods for `TxEip7702` ([#1221](https://github.com/alloy-rs/alloy/issues/1221)) + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Dependencies @@ -23,6 +38,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - [consensus] Add missing getter trait methods for `alloy_consensus::Transaction` ([#1197](https://github.com/alloy-rs/alloy/issues/1197)) - Release 0.2.1 - Chore : fix typos ([#1087](https://github.com/alloy-rs/alloy/issues/1087)) diff --git a/crates/contract/CHANGELOG.md b/crates/contract/CHANGELOG.md index 7ba37b6787a..a47485754f5 100644 --- a/crates/contract/CHANGELOG.md +++ b/crates/contract/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Release 0.2.1 - Release 0.2.0 - Fix unnameable types ([#1029](https://github.com/alloy-rs/alloy/issues/1029)) diff --git a/crates/eip7547/CHANGELOG.md b/crates/eip7547/CHANGELOG.md index 8470fd51c5b..1c20d59a82e 100644 --- a/crates/eip7547/CHANGELOG.md +++ b/crates/eip7547/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Release 0.2.1 - Release 0.2.0 diff --git a/crates/eips/CHANGELOG.md b/crates/eips/CHANGELOG.md index e4809481e77..a1bd97c3a68 100644 --- a/crates/eips/CHANGELOG.md +++ b/crates/eips/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Bug Fixes + +- [eips] No-std compat ([#1222](https://github.com/alloy-rs/alloy/issues/1222)) + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Bug Fixes @@ -32,6 +38,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Clippy für docs ([#1194](https://github.com/alloy-rs/alloy/issues/1194)) - [eip7702] Devnet3 changes ([#1056](https://github.com/alloy-rs/alloy/issues/1056)) - Release 0.2.1 diff --git a/crates/genesis/CHANGELOG.md b/crates/genesis/CHANGELOG.md index 386ed653940..a25f1dcdf92 100644 --- a/crates/genesis/CHANGELOG.md +++ b/crates/genesis/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Clippy für docs ([#1194](https://github.com/alloy-rs/alloy/issues/1194)) - Release 0.2.1 - Release 0.2.0 diff --git a/crates/json-rpc/CHANGELOG.md b/crates/json-rpc/CHANGELOG.md index 4f4ab9ac606..b9f9cedffae 100644 --- a/crates/json-rpc/CHANGELOG.md +++ b/crates/json-rpc/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Features + +- [`json-rpc`] Implement From U256 and String for SubId ([#1226](https://github.com/alloy-rs/alloy/issues/1226)) + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Bug Fixes @@ -19,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Clippy für docs ([#1194](https://github.com/alloy-rs/alloy/issues/1194)) - JSON-RPC 2.0 spelling ([#1146](https://github.com/alloy-rs/alloy/issues/1146)) - Release 0.2.1 diff --git a/crates/network-primitives/CHANGELOG.md b/crates/network-primitives/CHANGELOG.md index 0d14783e8d8..a2be30b8738 100644 --- a/crates/network-primitives/CHANGELOG.md +++ b/crates/network-primitives/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Release 0.2.1 ### Refactor diff --git a/crates/network/CHANGELOG.md b/crates/network/CHANGELOG.md index 6b2f0a26b90..ac4b8b90666 100644 --- a/crates/network/CHANGELOG.md +++ b/crates/network/CHANGELOG.md @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Remove async_trait from NetworkWallet ([#1160](https://github.com/alloy-rs/alloy/issues/1160)) - Add missing 7702 check ([#1137](https://github.com/alloy-rs/alloy/issues/1137)) - Release 0.2.1 diff --git a/crates/node-bindings/CHANGELOG.md b/crates/node-bindings/CHANGELOG.md index af9777df71a..3a10b988515 100644 --- a/crates/node-bindings/CHANGELOG.md +++ b/crates/node-bindings/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Bug Fixes + +- Anvil builder default port ([#1213](https://github.com/alloy-rs/alloy/issues/1213)) + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Bug Fixes @@ -15,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Release 0.2.1 - Release 0.2.0 diff --git a/crates/provider/CHANGELOG.md b/crates/provider/CHANGELOG.md index e04f483c42e..139e758badd 100644 --- a/crates/provider/CHANGELOG.md +++ b/crates/provider/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Features + +- [alloy-provider] Add abstraction for `NonceFiller` behavior ([#1108](https://github.com/alloy-rs/alloy/issues/1108)) + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Bug Fixes @@ -34,6 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Clippy für docs ([#1194](https://github.com/alloy-rs/alloy/issues/1194)) - Release 0.2.1 - Correctly cfg unused type ([#1117](https://github.com/alloy-rs/alloy/issues/1117)) diff --git a/crates/pubsub/CHANGELOG.md b/crates/pubsub/CHANGELOG.md index 03ca72542be..171b5b2965c 100644 --- a/crates/pubsub/CHANGELOG.md +++ b/crates/pubsub/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Release 0.2.1 - Release 0.2.0 - Fix unnameable types ([#1029](https://github.com/alloy-rs/alloy/issues/1029)) diff --git a/crates/rpc-client/CHANGELOG.md b/crates/rpc-client/CHANGELOG.md index 89b7a87a07f..53de2a84f6b 100644 --- a/crates/rpc-client/CHANGELOG.md +++ b/crates/rpc-client/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Release 0.2.1 - Release 0.2.0 - Fix unnameable types ([#1029](https://github.com/alloy-rs/alloy/issues/1029)) diff --git a/crates/rpc-types-admin/CHANGELOG.md b/crates/rpc-types-admin/CHANGELOG.md index 702b420443c..c562d3318af 100644 --- a/crates/rpc-types-admin/CHANGELOG.md +++ b/crates/rpc-types-admin/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Release 0.2.1 - Chore : fix typos ([#1087](https://github.com/alloy-rs/alloy/issues/1087)) - Release 0.2.0 diff --git a/crates/rpc-types-anvil/CHANGELOG.md b/crates/rpc-types-anvil/CHANGELOG.md index 71d302cfd9f..109428c82ce 100644 --- a/crates/rpc-types-anvil/CHANGELOG.md +++ b/crates/rpc-types-anvil/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Release 0.2.1 - Release 0.2.0 diff --git a/crates/rpc-types-beacon/CHANGELOG.md b/crates/rpc-types-beacon/CHANGELOG.md index 97b7d615fe0..81dbc4c816a 100644 --- a/crates/rpc-types-beacon/CHANGELOG.md +++ b/crates/rpc-types-beacon/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Clippy für docs ([#1194](https://github.com/alloy-rs/alloy/issues/1194)) - Release 0.2.1 - Release 0.2.0 diff --git a/crates/rpc-types-debug/CHANGELOG.md b/crates/rpc-types-debug/CHANGELOG.md index 38460702304..69372189c6f 100644 --- a/crates/rpc-types-debug/CHANGELOG.md +++ b/crates/rpc-types-debug/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [rpc-types] `debug_executionWitness` ([#1178](https://github.com/alloy-rs/alloy/issues/1178)) +### Miscellaneous Tasks + +- Release 0.3.0 + [`alloy`]: https://crates.io/crates/alloy [alloy]: https://crates.io/crates/alloy [`alloy-core`]: https://crates.io/crates/alloy-core diff --git a/crates/rpc-types-engine/CHANGELOG.md b/crates/rpc-types-engine/CHANGELOG.md index 883cef7d143..a02ac157920 100644 --- a/crates/rpc-types-engine/CHANGELOG.md +++ b/crates/rpc-types-engine/CHANGELOG.md @@ -23,6 +23,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Clippy für docs ([#1194](https://github.com/alloy-rs/alloy/issues/1194)) - [dep] Feature gate jwt in engine types ([#1131](https://github.com/alloy-rs/alloy/issues/1131)) - Release 0.2.1 diff --git a/crates/rpc-types-eth/CHANGELOG.md b/crates/rpc-types-eth/CHANGELOG.md index 1075abc6343..f6cb2578afc 100644 --- a/crates/rpc-types-eth/CHANGELOG.md +++ b/crates/rpc-types-eth/CHANGELOG.md @@ -40,6 +40,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Rm Rich type ([#1195](https://github.com/alloy-rs/alloy/issues/1195)) - Clippy für docs ([#1194](https://github.com/alloy-rs/alloy/issues/1194)) - Remove RichBlock and RichHeader types ([#1185](https://github.com/alloy-rs/alloy/issues/1185)) diff --git a/crates/rpc-types-mev/CHANGELOG.md b/crates/rpc-types-mev/CHANGELOG.md index 5702f4ac04f..d2989edff30 100644 --- a/crates/rpc-types-mev/CHANGELOG.md +++ b/crates/rpc-types-mev/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Clippy für docs ([#1194](https://github.com/alloy-rs/alloy/issues/1194)) - Release 0.2.1 - Chore : fix typos ([#1087](https://github.com/alloy-rs/alloy/issues/1087)) diff --git a/crates/rpc-types-trace/CHANGELOG.md b/crates/rpc-types-trace/CHANGELOG.md index 64b3a719899..a76bb7a0944 100644 --- a/crates/rpc-types-trace/CHANGELOG.md +++ b/crates/rpc-types-trace/CHANGELOG.md @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Rm Rich type ([#1195](https://github.com/alloy-rs/alloy/issues/1195)) - Clippy für docs ([#1194](https://github.com/alloy-rs/alloy/issues/1194)) - Release 0.2.1 diff --git a/crates/rpc-types-txpool/CHANGELOG.md b/crates/rpc-types-txpool/CHANGELOG.md index b0bec33dba3..659a3fcd676 100644 --- a/crates/rpc-types-txpool/CHANGELOG.md +++ b/crates/rpc-types-txpool/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Release 0.2.1 - Release 0.2.0 diff --git a/crates/rpc-types/CHANGELOG.md b/crates/rpc-types/CHANGELOG.md index 8e3d2fb66f9..8e8008ac46a 100644 --- a/crates/rpc-types/CHANGELOG.md +++ b/crates/rpc-types/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Release 0.2.1 - Release 0.2.0 diff --git a/crates/serde/CHANGELOG.md b/crates/serde/CHANGELOG.md index 675bfabadf8..1bfadc52d40 100644 --- a/crates/serde/CHANGELOG.md +++ b/crates/serde/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Release 0.2.1 - Release 0.2.0 - Fix unnameable types ([#1029](https://github.com/alloy-rs/alloy/issues/1029)) diff --git a/crates/signer-aws/CHANGELOG.md b/crates/signer-aws/CHANGELOG.md index 2dade179b6c..d4bb9f32e1e 100644 --- a/crates/signer-aws/CHANGELOG.md +++ b/crates/signer-aws/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Release 0.2.1 - Release 0.2.0 diff --git a/crates/signer-gcp/CHANGELOG.md b/crates/signer-gcp/CHANGELOG.md index ab10ea16025..ea4c97e1900 100644 --- a/crates/signer-gcp/CHANGELOG.md +++ b/crates/signer-gcp/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Release 0.2.1 - Release 0.2.0 diff --git a/crates/signer-ledger/CHANGELOG.md b/crates/signer-ledger/CHANGELOG.md index 91bf2e9b6ae..b02d7671342 100644 --- a/crates/signer-ledger/CHANGELOG.md +++ b/crates/signer-ledger/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Release 0.2.1 - Release 0.2.0 diff --git a/crates/signer-local/CHANGELOG.md b/crates/signer-local/CHANGELOG.md index d6ef4068366..82908cd00df 100644 --- a/crates/signer-local/CHANGELOG.md +++ b/crates/signer-local/CHANGELOG.md @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Release 0.2.1 - Release 0.2.0 - Fix unnameable types ([#1029](https://github.com/alloy-rs/alloy/issues/1029)) diff --git a/crates/signer-trezor/CHANGELOG.md b/crates/signer-trezor/CHANGELOG.md index d809cce6144..f3629b8e143 100644 --- a/crates/signer-trezor/CHANGELOG.md +++ b/crates/signer-trezor/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Release 0.2.1 - Release 0.2.0 diff --git a/crates/signer/CHANGELOG.md b/crates/signer/CHANGELOG.md index 9374ee9beba..efca8a2e14d 100644 --- a/crates/signer/CHANGELOG.md +++ b/crates/signer/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Release 0.2.1 - Release 0.2.0 diff --git a/crates/transport-http/CHANGELOG.md b/crates/transport-http/CHANGELOG.md index efa8ea635c3..a2b88a9d0af 100644 --- a/crates/transport-http/CHANGELOG.md +++ b/crates/transport-http/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Release 0.2.1 - Release 0.2.0 diff --git a/crates/transport-ipc/CHANGELOG.md b/crates/transport-ipc/CHANGELOG.md index dc4d68fd3c2..90545888075 100644 --- a/crates/transport-ipc/CHANGELOG.md +++ b/crates/transport-ipc/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Release 0.2.1 - Release 0.2.0 diff --git a/crates/transport-ws/CHANGELOG.md b/crates/transport-ws/CHANGELOG.md index 46c0b325c3d..036104ab7d5 100644 --- a/crates/transport-ws/CHANGELOG.md +++ b/crates/transport-ws/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Release 0.2.1 - Release 0.2.0 diff --git a/crates/transport/CHANGELOG.md b/crates/transport/CHANGELOG.md index baf3c42ce26..61ecee9f62e 100644 --- a/crates/transport/CHANGELOG.md +++ b/crates/transport/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.0 - Release 0.2.1 - Release 0.2.0 - Fix unnameable types ([#1029](https://github.com/alloy-rs/alloy/issues/1029)) From 81f4ab815305d5699841cf49a991c927a1d55815 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 3 Sep 2024 12:52:47 +0200 Subject: [PATCH 129/186] chore: derive more default features false (#1230) --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index f4909ffe980..bca3ffc4c47 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -133,7 +133,7 @@ semver = "1.0" thiserror = "1.0" thiserror-no-std = "2.0.2" url = "2.5" -derive_more = "1.0.0" +derive_more = { version = "1.0.0", default-features = false } ## serde serde = { version = "1.0", default-features = false, features = [ From 06e0ae9a3694fc45a8abb07a0ef4b5528f048f76 Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Tue, 3 Sep 2024 23:41:41 +0530 Subject: [PATCH 130/186] feat(network-primitives): expose more fields via block response traits (#1229) * feat(network-primitives): expose more fields in HeaderResponse * feat(network-primitives): expose `other` fields in BlockResponse * nits --- crates/network-primitives/src/traits.rs | 51 ++++++++++++++++++++++++- crates/rpc-types-eth/src/block.rs | 16 ++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/crates/network-primitives/src/traits.rs b/crates/network-primitives/src/traits.rs index 64fc692cfa6..de6f4788796 100644 --- a/crates/network-primitives/src/traits.rs +++ b/crates/network-primitives/src/traits.rs @@ -1,4 +1,4 @@ -use alloy_primitives::{Address, BlockHash, Bytes, TxHash, U256}; +use alloy_primitives::{Address, BlockHash, Bytes, TxHash, B256, U256}; use alloy_serde::WithOtherFields; use crate::BlockTransactions; @@ -67,6 +67,30 @@ pub trait HeaderResponse { /// Blob fee for the next block (if EIP-4844 is supported) fn next_block_blob_fee(&self) -> Option; + + /// Coinbase/Miner of the block + fn coinbase(&self) -> Address; + + /// Gas limit of the block + fn gas_limit(&self) -> u128; + + /// Mix hash of the block + /// + /// Before the merge this proves, combined with the nonce, that a sufficient amount of + /// computation has been carried out on this block: the Proof-of-Work (PoW). + /// + /// After the merge this is `prevRandao`: Randomness value for the generated payload. + /// + /// This is an Option because it is not always set by non-ethereum networks. + /// + /// See also + /// And + fn mix_hash(&self) -> Option; + + /// Difficulty of the block + /// + /// Unused after the Paris (AKA the merge) upgrade, and replaced by `prevrandao`. + fn difficulty(&self) -> U256; } /// Block JSON-RPC response. @@ -84,6 +108,11 @@ pub trait BlockResponse { /// Mutable reference to block transactions fn transactions_mut(&mut self) -> &mut BlockTransactions; + + /// Returns the `other` field from `WithOtherFields` type. + fn other_fields(&self) -> Option<&alloy_serde::OtherFields> { + None + } } impl TransactionResponse for WithOtherFields { @@ -145,6 +174,10 @@ impl BlockResponse for WithOtherFields { fn transactions_mut(&mut self) -> &mut BlockTransactions { self.inner.transactions_mut() } + + fn other_fields(&self) -> Option<&alloy_serde::OtherFields> { + Some(&self.other) + } } impl HeaderResponse for WithOtherFields { @@ -171,4 +204,20 @@ impl HeaderResponse for WithOtherFields { fn next_block_blob_fee(&self) -> Option { self.inner.next_block_blob_fee() } + + fn coinbase(&self) -> Address { + self.inner.coinbase() + } + + fn gas_limit(&self) -> u128 { + self.inner.gas_limit() + } + + fn mix_hash(&self) -> Option { + self.inner.mix_hash() + } + + fn difficulty(&self) -> U256 { + self.inner.difficulty() + } } diff --git a/crates/rpc-types-eth/src/block.rs b/crates/rpc-types-eth/src/block.rs index 42474cdb549..5fd1cfa00e3 100644 --- a/crates/rpc-types-eth/src/block.rs +++ b/crates/rpc-types-eth/src/block.rs @@ -228,6 +228,22 @@ impl HeaderResponse for Header { fn next_block_blob_fee(&self) -> Option { self.next_block_blob_fee() } + + fn coinbase(&self) -> Address { + self.miner + } + + fn gas_limit(&self) -> u128 { + self.gas_limit + } + + fn mix_hash(&self) -> Option { + self.mix_hash + } + + fn difficulty(&self) -> U256 { + self.difficulty + } } /// Error that can occur when converting other types to blocks From 68065370137088b414f4796e2b3b018e36031e01 Mon Sep 17 00:00:00 2001 From: Dan Cline <6798349+Rjected@users.noreply.github.com> Date: Tue, 3 Sep 2024 15:48:31 -0400 Subject: [PATCH 131/186] feat(rpc-types-engine): add forkchoice state zero helpers (#1231) feat: add forkchoice state zero helpers --- crates/rpc-types-engine/src/forkchoice.rs | 35 +++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/crates/rpc-types-engine/src/forkchoice.rs b/crates/rpc-types-engine/src/forkchoice.rs index 781ae7b651b..bcf0be59f3a 100644 --- a/crates/rpc-types-engine/src/forkchoice.rs +++ b/crates/rpc-types-engine/src/forkchoice.rs @@ -30,6 +30,41 @@ pub struct ForkchoiceState { pub finalized_block_hash: B256, } +impl ForkchoiceState { + /// Returns the `head_block_hash`, only if it is not [`B256::ZERO`], otherwise this returns + /// [`None`]. + #[inline] + pub fn state_head_hash(&self) -> Option { + if self.head_block_hash.is_zero() { + None + } else { + Some(self.head_block_hash) + } + } + + /// Returns the `safe_block_hash`, only if it is not [`B256::ZERO`], otherwise this returns + /// [`None`]. + #[inline] + pub fn state_safe_hash(&self) -> Option { + if self.safe_block_hash.is_zero() { + None + } else { + Some(self.safe_block_hash) + } + } + + /// Returns the `finalized_block_hash`, only if it is not [`B256::ZERO`], otherwise this + /// returns [`None`]. + #[inline] + pub fn state_finalized_hash(&self) -> Option { + if self.finalized_block_hash.is_zero() { + None + } else { + Some(self.finalized_block_hash) + } + } +} + /// A standalone forkchoice update errors for RPC. /// /// These are considered hard RPC errors and are _not_ returned as [PayloadStatus] or From de56cb96a59a73e1483b07974f3a2d5db13944eb Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Wed, 4 Sep 2024 07:34:28 -0700 Subject: [PATCH 132/186] consensus: implement `Arbitrary` for `Header` (#1235) * consensus: implement Arbitrary for Header * fix function call * fn visibility --- crates/consensus/src/header.rs | 77 ++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/crates/consensus/src/header.rs b/crates/consensus/src/header.rs index f593b873929..5cda6d18a89 100644 --- a/crates/consensus/src/header.rs +++ b/crates/consensus/src/header.rs @@ -527,6 +527,83 @@ impl Decodable for Header { } } +/// Generates a header which is valid __with respect to past and future forks__. This means, for +/// example, that if the withdrawals root is present, the base fee per gas is also present. +/// +/// If blob gas used were present, then the excess blob gas and parent beacon block root are also +/// present. In this example, the withdrawals root would also be present. +/// +/// This __does not, and should not guarantee__ that the header is valid with respect to __anything +/// else__. +#[cfg(any(test, feature = "arbitrary"))] +pub(crate) const fn generate_valid_header( + mut header: Header, + eip_4844_active: bool, + blob_gas_used: u128, + excess_blob_gas: u128, + parent_beacon_block_root: B256, +) -> Header { + // Clear all related fields if EIP-1559 is inactive + if header.base_fee_per_gas.is_none() { + header.withdrawals_root = None; + } + + // Set fields based on EIP-4844 being active + if eip_4844_active { + header.blob_gas_used = Some(blob_gas_used); + header.excess_blob_gas = Some(excess_blob_gas); + header.parent_beacon_block_root = Some(parent_beacon_block_root); + } else { + header.blob_gas_used = None; + header.excess_blob_gas = None; + header.parent_beacon_block_root = None; + } + + // Placeholder for future EIP adjustments + header.requests_root = None; + + header +} + +#[cfg(any(test, feature = "arbitrary"))] +impl<'a> arbitrary::Arbitrary<'a> for Header { + fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result { + // Generate an arbitrary header, passing it to the generate_valid_header function to make + // sure it is valid _with respect to hardforks only_. + let base = Self { + parent_hash: u.arbitrary()?, + ommers_hash: u.arbitrary()?, + beneficiary: u.arbitrary()?, + state_root: u.arbitrary()?, + transactions_root: u.arbitrary()?, + receipts_root: u.arbitrary()?, + logs_bloom: u.arbitrary()?, + difficulty: u.arbitrary()?, + number: u.arbitrary()?, + gas_limit: u.arbitrary()?, + gas_used: u.arbitrary()?, + timestamp: u.arbitrary()?, + extra_data: u.arbitrary()?, + mix_hash: u.arbitrary()?, + nonce: u.arbitrary()?, + base_fee_per_gas: u.arbitrary()?, + blob_gas_used: u.arbitrary()?, + excess_blob_gas: u.arbitrary()?, + parent_beacon_block_root: u.arbitrary()?, + requests_root: u.arbitrary()?, + withdrawals_root: u.arbitrary()?, + }; + + Ok(generate_valid_header( + base, + u.arbitrary()?, + u.arbitrary()?, + u.arbitrary()?, + u.arbitrary()?, + )) + } +} + #[cfg(test)] mod tests { use super::*; From 68d245eb6f8d2541157f37d204f7b3a26b9bdc46 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Wed, 4 Sep 2024 07:51:50 -0700 Subject: [PATCH 133/186] consensus: impl parent_num_hash for Header (#1238) --- crates/consensus/src/header.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crates/consensus/src/header.rs b/crates/consensus/src/header.rs index 5cda6d18a89..73fe1252432 100644 --- a/crates/consensus/src/header.rs +++ b/crates/consensus/src/header.rs @@ -1,6 +1,7 @@ use alloy_eips::{ eip1559::{calc_next_block_base_fee, BaseFeeParams}, eip4844::{calc_blob_gasprice, calc_excess_blob_gas}, + BlockNumHash, }; use alloy_primitives::{ b256, keccak256, Address, BlockNumber, Bloom, Bytes, Sealable, B256, B64, U256, @@ -344,6 +345,11 @@ impl Header { length } + + /// Returns the parent block's number and hash + pub const fn parent_num_hash(&self) -> BlockNumHash { + BlockNumHash { number: self.number.saturating_sub(1), hash: self.parent_hash } + } } impl Encodable for Header { From aa1f2349dac04a0b459bb8d9896b49046c5251fc Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Wed, 4 Sep 2024 07:53:41 -0700 Subject: [PATCH 134/186] consensus: impl `is_zero_difficulty` for `Header` (#1236) consensus: impl is_zero_difficulty for Header Co-authored-by: Matthias Seitz --- crates/consensus/src/header.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/crates/consensus/src/header.rs b/crates/consensus/src/header.rs index 73fe1252432..3472baf07a7 100644 --- a/crates/consensus/src/header.rs +++ b/crates/consensus/src/header.rs @@ -350,6 +350,19 @@ impl Header { pub const fn parent_num_hash(&self) -> BlockNumHash { BlockNumHash { number: self.number.saturating_sub(1), hash: self.parent_hash } } + + /// Checks if the block's difficulty is set to zero, indicating a Proof-of-Stake header. + /// + /// This function is linked to EIP-3675, proposing the consensus upgrade to Proof-of-Stake: + /// [EIP-3675](https://eips.ethereum.org/EIPS/eip-3675#replacing-difficulty-with-0) + /// + /// Verifies whether, as per the EIP, the block's difficulty is updated to zero, + /// signifying the transition to a Proof-of-Stake mechanism. + /// + /// Returns `true` if the block's difficulty matches the constant zero set by the EIP. + pub fn is_zero_difficulty(&self) -> bool { + self.difficulty.is_zero() + } } impl Encodable for Header { From 7cb68046b6f8bb6691a0446abfc98586f95ae1f2 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Wed, 4 Sep 2024 07:55:08 -0700 Subject: [PATCH 135/186] consensus: impl `exceeds_allowed_future_timestamp` for `Header` (#1237) consensus: impl exceeds_allowed_future_timestamp for Header Co-authored-by: Matthias Seitz --- crates/consensus/src/header.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/crates/consensus/src/header.rs b/crates/consensus/src/header.rs index 3472baf07a7..ae7bed24ae1 100644 --- a/crates/consensus/src/header.rs +++ b/crates/consensus/src/header.rs @@ -1,6 +1,7 @@ use alloy_eips::{ eip1559::{calc_next_block_base_fee, BaseFeeParams}, eip4844::{calc_blob_gasprice, calc_excess_blob_gas}, + merge::ALLOWED_FUTURE_BLOCK_TIME_SECONDS, BlockNumHash, }; use alloy_primitives::{ @@ -363,6 +364,15 @@ impl Header { pub fn is_zero_difficulty(&self) -> bool { self.difficulty.is_zero() } + + /// Checks if the block's timestamp is in the future based on the present timestamp. + /// + /// Clock can drift but this can be consensus issue. + /// + /// Note: This check is relevant only pre-merge. + pub const fn exceeds_allowed_future_timestamp(&self, present_timestamp: u64) -> bool { + self.timestamp > present_timestamp + ALLOWED_FUTURE_BLOCK_TIME_SECONDS + } } impl Encodable for Header { From 0cb54b5da93be383f34b20221ddf9d58ce82a58d Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 4 Sep 2024 17:15:14 +0200 Subject: [PATCH 136/186] chore: optional derive more (#1239) --- crates/eips/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/eips/Cargo.toml b/crates/eips/Cargo.toml index 55dc96a3315..7e352aeb548 100644 --- a/crates/eips/Cargo.toml +++ b/crates/eips/Cargo.toml @@ -59,7 +59,7 @@ serde_json.workspace = true [features] default = ["std", "kzg-sidecar"] -std = ["alloy-primitives/std", "alloy-rlp/std", "derive_more/std", +std = ["alloy-primitives/std", "alloy-rlp/std", "derive_more?/std", "serde?/std", "c-kzg?/std", "once_cell?/std"] serde = ["dep:alloy-serde", "dep:serde", "alloy-primitives/serde", "c-kzg?/serde", "alloy-eip2930/serde", "alloy-eip7702/serde"] From 002aed5726e47696edf7e125d11c2794ceaca5e4 Mon Sep 17 00:00:00 2001 From: zerosnacks <95942363+zerosnacks@users.noreply.github.com> Date: Thu, 5 Sep 2024 15:17:45 +0200 Subject: [PATCH 137/186] feat: add Reth node bindings (#1092) * generalize geth into node * add basic reth setup * basic spawning and capturing of ports works, shutdown does not * add auth_port, p2p_port * clean up * fix geth tests * simplify abstraction * clean up * add explicit `dev` mode command, reth remains open * --chain takes path or string, not id * add support for UDP endpoint extraction from keys * clean up, add dev flag * tag as dev * add option to set block time * add block time * disable peer persistence if discovery is disabled * update binaries * add reth install in github workflow * fix build * fix doctest * windows geth build is zipped * fix name * fix path to reth binary * tar is flat * fix url * fix output path * reth is already extracted to the root * reth renders via stdout * disable dev by default, enabling it with .dev() * make sure to exit when running into fatal error * add tests to cover the feature set * try debugging windows * run binary install in parallel * disable discovery on blocktime dev * attempt to fix on windows by not using tempdir * re-enable tempdir, attempt to get full error log on windows * ignore tests on windows, CI of Windows is not compatible: [crates\node-bindings\src\nodes\reth.rs:369:13] &line = "2024-09-04T12:39:10.637528Z INFO reth::cli: Opening database path=\"C:\\\\Users\\\\RUNNER~1\\\\AppData\\\\Local\\\\Temp\\\\.tmp4XoSee\\\\db\"\n" [crates\node-bindings\src\nodes\reth.rs:369:13] &line = "2024-09-04T12:39:10.731699Z ERROR reth::cli: shutting down due to error\n" Error: failed to open the database: environment or database is not compatible with the requested operation or flags (-30784) Location: /project/crates/storage/db/src/mdbx.rs:28:8 * only install on linux * temporarily re-enable windows to test error catching * revert --- .github/scripts/install_test_binaries.sh | 52 +- crates/node-bindings/src/lib.rs | 32 +- crates/node-bindings/src/node.rs | 68 +++ crates/node-bindings/src/{ => nodes}/anvil.rs | 0 crates/node-bindings/src/{ => nodes}/geth.rs | 286 ++++----- crates/node-bindings/src/nodes/mod.rs | 5 + crates/node-bindings/src/nodes/reth.rs | 542 ++++++++++++++++++ crates/node-bindings/src/utils.rs | 87 +++ 8 files changed, 862 insertions(+), 210 deletions(-) create mode 100644 crates/node-bindings/src/node.rs rename crates/node-bindings/src/{ => nodes}/anvil.rs (100%) rename crates/node-bindings/src/{ => nodes}/geth.rs (77%) create mode 100644 crates/node-bindings/src/nodes/mod.rs create mode 100644 crates/node-bindings/src/nodes/reth.rs create mode 100644 crates/node-bindings/src/utils.rs diff --git a/.github/scripts/install_test_binaries.sh b/.github/scripts/install_test_binaries.sh index 3e89dbaea22..53f7d513d00 100755 --- a/.github/scripts/install_test_binaries.sh +++ b/.github/scripts/install_test_binaries.sh @@ -3,7 +3,8 @@ # Note: intended for use only with CI (x86_64 Ubuntu, MacOS or Windows) set -e -GETH_BUILD=${GETH_BUILD:-"1.14.0-87246f3c"} +GETH_BUILD=${GETH_BUILD:-"1.14.8-a9523b64"} +RETH_BUILD=${RETH_BUILD:-"1.0.6"} BIN_DIR=${BIN_DIR:-"$HOME/bin"} @@ -17,32 +18,49 @@ main() { echo "$BIN_DIR" >> "$GITHUB_PATH" fi - install_geth + install_geth & + install_reth & - echo "" - echo "Installed Geth:" - geth version + wait } # Installs geth from https://geth.ethereum.org/downloads install_geth() { case "$PLATFORM" in - linux|darwin) - name="geth-$PLATFORM-amd64-$GETH_BUILD" - curl -s "https://gethstore.blob.core.windows.net/builds/$name.tar.gz" | tar -xzf - - mv -f "$name/geth" ./ - rm -rf "$name" + linux) + NAME="geth-$PLATFORM-amd64-$GETH_BUILD" + curl -sL "https://gethstore.blob.core.windows.net/builds/$NAME.tar.gz" | tar -xzf - + mv -f "$NAME/geth" ./ + rm -rf "$NAME" chmod +x geth ;; *) - name="geth-windows-amd64-$GETH_BUILD" - zip="$name.zip" - curl -so "$zip" "https://gethstore.blob.core.windows.net/builds/$zip" - unzip "$zip" - mv -f "$name/geth.exe" ./ - rm -rf "$name" "$zip" + NAME="geth-windows-amd64-$GETH_BUILD" + curl -so $NAME.zip "https://gethstore.blob.core.windows.net/builds/$NAME.zip" + unzip $NAME.zip + mv -f "$NAME/geth.exe" ./ + rm -rf "$NAME" "$NAME.zip" + ;; + esac + + echo "" + echo "Installed Geth:" + geth version +} + +# Install reth from https://github.com/paradigmxyz/reth/releases +install_reth() { + case "$PLATFORM" in + linux) + NAME="reth-v$RETH_BUILD-x86_64-unknown-linux-gnu" + curl -sL "https://github.com/paradigmxyz/reth/releases/download/v$RETH_BUILD/$NAME.tar.gz" | tar -xzf - + chmod +x reth + + echo "" + echo "Installed Reth:" + reth --version ;; esac } -main +main \ No newline at end of file diff --git a/crates/node-bindings/src/lib.rs b/crates/node-bindings/src/lib.rs index dc99b996839..6df8d1e9ff4 100644 --- a/crates/node-bindings/src/lib.rs +++ b/crates/node-bindings/src/lib.rs @@ -11,37 +11,35 @@ extern crate tracing; use alloy_primitives::U256; -pub mod anvil; -pub use anvil::{Anvil, AnvilInstance}; +pub mod nodes; +pub use nodes::{ + anvil::{self, Anvil, AnvilInstance}, + geth::{self, Geth, GethInstance}, + reth::{self, Reth, RethInstance}, +}; -pub mod geth; -pub use geth::{Geth, GethInstance}; +mod node; +pub use node::*; + +mod utils; +use utils::*; /// 1 Ether = 1e18 Wei == 0x0de0b6b3a7640000 Wei pub const WEI_IN_ETHER: U256 = U256::from_limbs([0x0de0b6b3a7640000, 0x0, 0x0, 0x0]); /// The number of blocks from the past for which the fee rewards are fetched for fee estimation. pub const EIP1559_FEE_ESTIMATION_PAST_BLOCKS: u64 = 10; + /// The default percentile of gas premiums that are fetched for fee estimation. pub const EIP1559_FEE_ESTIMATION_REWARD_PERCENTILE: f64 = 5.0; + /// The default max priority fee per gas, used in case the base fee is within a threshold. pub const EIP1559_FEE_ESTIMATION_DEFAULT_PRIORITY_FEE: u64 = 3_000_000_000; + /// The threshold for base fee below which we use the default priority fee, and beyond which we /// estimate an appropriate value for priority fee. pub const EIP1559_FEE_ESTIMATION_PRIORITY_FEE_TRIGGER: u64 = 100_000_000_000; + /// The threshold max change/difference (in %) at which we will ignore the fee history values /// under it. pub const EIP1559_FEE_ESTIMATION_THRESHOLD_MAX_CHANGE: i64 = 200; - -/// A bit of hack to find an unused TCP port. -/// -/// Does not guarantee that the given port is unused after the function exists, just that it was -/// unused before the function started (i.e., it does not reserve a port). -fn unused_port() -> u16 { - let listener = std::net::TcpListener::bind("127.0.0.1:0") - .expect("Failed to create TCP listener to find unused port"); - - let local_addr = - listener.local_addr().expect("Failed to read TCP listener local_addr to find unused port"); - local_addr.port() -} diff --git a/crates/node-bindings/src/node.rs b/crates/node-bindings/src/node.rs new file mode 100644 index 00000000000..b89056142d2 --- /dev/null +++ b/crates/node-bindings/src/node.rs @@ -0,0 +1,68 @@ +//! Node-related types and constants. + +use std::time::Duration; +use thiserror::Error; + +/// How long we will wait for the node to indicate that it is ready. +pub const NODE_STARTUP_TIMEOUT: Duration = Duration::from_secs(10); + +/// Timeout for waiting for the node to add a peer. +pub const NODE_DIAL_LOOP_TIMEOUT: Duration = Duration::from_secs(20); + +/// Errors that can occur when working with a node instance. +#[derive(Debug)] +pub enum NodeInstanceError { + /// Timed out waiting for a message from node's stderr. + Timeout(String), + + /// A line could not be read from the node's stderr. + ReadLineError(std::io::Error), + + /// The child node process's stderr was not captured. + NoStderr, + + /// The child node process's stdout was not captured. + NoStdout, +} + +/// Errors that can occur when working with the node. +#[derive(Debug, Error)] +pub enum NodeError { + /// The chain id was not set. + #[error("the chain ID was not set")] + ChainIdNotSet, + /// Could not create the data directory. + #[error("could not create directory: {0}")] + CreateDirError(std::io::Error), + /// No stderr was captured from the child process. + #[error("no stderr was captured from the process")] + NoStderr, + /// No stdout was captured from the child process. + #[error("no stdout was captured from the process")] + NoStdout, + /// Timed out waiting for the node to start. + #[error("timed out waiting for node to spawn; is the node binary installed?")] + Timeout, + /// Encountered a fatal error. + #[error("fatal error: {0}")] + Fatal(String), + /// A line could not be read from the node stderr. + #[error("could not read line from node stderr: {0}")] + ReadLineError(std::io::Error), + /// Genesis error + #[error("genesis error occurred: {0}")] + GenesisError(String), + /// Node init error + #[error("node init error occurred")] + InitError, + /// Spawn node error + #[error("could not spawn node: {0}")] + SpawnError(std::io::Error), + /// Wait error + #[error("could not wait for node to exit: {0}")] + WaitError(std::io::Error), + + /// Clique private key error + #[error("clique address error: {0}")] + CliqueAddressError(String), +} diff --git a/crates/node-bindings/src/anvil.rs b/crates/node-bindings/src/nodes/anvil.rs similarity index 100% rename from crates/node-bindings/src/anvil.rs rename to crates/node-bindings/src/nodes/anvil.rs diff --git a/crates/node-bindings/src/geth.rs b/crates/node-bindings/src/nodes/geth.rs similarity index 77% rename from crates/node-bindings/src/geth.rs rename to crates/node-bindings/src/nodes/geth.rs index 4c61b153a86..a87418928e3 100644 --- a/crates/node-bindings/src/geth.rs +++ b/crates/node-bindings/src/nodes/geth.rs @@ -1,45 +1,64 @@ -//! Utilities for launching a go-ethereum dev-mode instance. +//! Utilities for launching a Geth dev-mode instance. -use crate::unused_port; +use crate::{ + extract_endpoint, extract_value, unused_port, NodeError, NodeInstanceError, + NODE_DIAL_LOOP_TIMEOUT, NODE_STARTUP_TIMEOUT, +}; use alloy_genesis::{CliqueConfig, Genesis}; use alloy_primitives::Address; use k256::ecdsa::SigningKey; use std::{ - borrow::Cow, fs::{create_dir, File}, io::{BufRead, BufReader}, - net::SocketAddr, path::PathBuf, process::{Child, ChildStderr, Command, Stdio}, - time::{Duration, Instant}, + time::Instant, }; use tempfile::tempdir; -use thiserror::Error; use url::Url; -/// How long we will wait for geth to indicate that it is ready. -const GETH_STARTUP_TIMEOUT: Duration = Duration::from_secs(10); - -/// Timeout for waiting for geth to add a peer. -const GETH_DIAL_LOOP_TIMEOUT: Duration = Duration::from_secs(20); - /// The exposed APIs const API: &str = "eth,net,web3,txpool,admin,personal,miner,debug"; /// The geth command const GETH: &str = "geth"; -/// Errors that can occur when working with the [`GethInstance`]. -#[derive(Debug)] -pub enum GethInstanceError { - /// Timed out waiting for a message from geth's stderr. - Timeout(String), +/// Whether or not node is in `dev` mode and configuration options that depend on the mode. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum NodeMode { + /// Options that can be set in dev mode + Dev(DevOptions), + /// Options that cannot be set in dev mode + NonDev(PrivateNetOptions), +} + +impl Default for NodeMode { + fn default() -> Self { + Self::Dev(Default::default()) + } +} + +/// Configuration options that can be set in dev mode. +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] +pub struct DevOptions { + /// The interval at which the dev chain will mine new blocks. + pub block_time: Option, +} + +/// Configuration options that cannot be set in dev mode. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub struct PrivateNetOptions { + /// The p2p port to use. + pub p2p_port: Option, - /// A line could not be read from the geth stderr. - ReadLineError(std::io::Error), + /// Whether or not peer discovery is enabled. + pub discovery: bool, +} - /// The child geth process's stderr was not captured. - NoStderr, +impl Default for PrivateNetOptions { + fn default() -> Self { + Self { p2p_port: None, discovery: true } + } } /// A geth instance. Will close the instance when dropped. @@ -49,9 +68,10 @@ pub enum GethInstanceError { pub struct GethInstance { pid: Child, port: u16, + p2p_port: Option, + auth_port: Option, ipc: Option, data_dir: Option, - p2p_port: Option, genesis: Option, clique_private_key: Option, } @@ -67,6 +87,11 @@ impl GethInstance { self.p2p_port } + /// Returns the auth port of this instance + pub const fn auth_port(&self) -> Option { + self.auth_port + } + /// Returns the HTTP endpoint of this instance #[doc(alias = "http_endpoint")] pub fn endpoint(&self) -> String { @@ -114,22 +139,22 @@ impl GethInstance { /// /// This leaves a `None` in its place, so calling methods that require a stderr to be present /// will fail if called after this. - pub fn stderr(&mut self) -> Result { - self.pid.stderr.take().ok_or(GethInstanceError::NoStderr) + pub fn stderr(&mut self) -> Result { + self.pid.stderr.take().ok_or(NodeInstanceError::NoStderr) } /// Blocks until geth adds the specified peer, using 20s as the timeout. /// /// Requires the stderr to be present in the `GethInstance`. - pub fn wait_to_add_peer(&mut self, id: &str) -> Result<(), GethInstanceError> { - let mut stderr = self.pid.stderr.as_mut().ok_or(GethInstanceError::NoStderr)?; + pub fn wait_to_add_peer(&mut self, id: &str) -> Result<(), NodeInstanceError> { + let mut stderr = self.pid.stderr.as_mut().ok_or(NodeInstanceError::NoStderr)?; let mut err_reader = BufReader::new(&mut stderr); let mut line = String::new(); let start = Instant::now(); - while start.elapsed() < GETH_DIAL_LOOP_TIMEOUT { + while start.elapsed() < NODE_DIAL_LOOP_TIMEOUT { line.clear(); - err_reader.read_line(&mut line).map_err(GethInstanceError::ReadLineError)?; + err_reader.read_line(&mut line).map_err(NodeInstanceError::ReadLineError)?; // geth ids are truncated let truncated_id = if id.len() > 16 { &id[..16] } else { id }; @@ -137,7 +162,7 @@ impl GethInstance { return Ok(()); } } - Err(GethInstanceError::Timeout("Timed out waiting for geth to add a peer".into())) + Err(NodeInstanceError::Timeout("Timed out waiting for geth to add a peer".into())) } } @@ -147,82 +172,6 @@ impl Drop for GethInstance { } } -/// Whether or not geth is in `dev` mode and configuration options that depend on the mode. -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub enum GethMode { - /// Options that can be set in dev mode - Dev(DevOptions), - /// Options that cannot be set in dev mode - NonDev(PrivateNetOptions), -} - -impl Default for GethMode { - fn default() -> Self { - Self::Dev(Default::default()) - } -} - -/// Configuration options that can be set in dev mode. -#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] -pub struct DevOptions { - /// The interval at which the dev chain will mine new blocks. - pub block_time: Option, -} - -/// Configuration options that cannot be set in dev mode. -#[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub struct PrivateNetOptions { - /// The p2p port to use. - pub p2p_port: Option, - - /// Whether or not peer discovery is enabled. - pub discovery: bool, -} - -impl Default for PrivateNetOptions { - fn default() -> Self { - Self { p2p_port: None, discovery: true } - } -} - -/// Errors that can occur when working with the [`Geth`]. -#[derive(Debug, Error)] -pub enum GethError { - /// Clique private key error - #[error("clique address error: {0}")] - CliqueAddressError(String), - /// The chain id was not set. - #[error("the chain ID was not set")] - ChainIdNotSet, - /// Could not create the data directory. - #[error("could not create directory: {0}")] - CreateDirError(std::io::Error), - /// No stderr was captured from the child process. - #[error("no stderr was captured from the process")] - NoStderr, - /// Timed out waiting for geth to start. - #[error("timed out waiting for geth to spawn; is geth installed?")] - Timeout, - /// Encountered a fatal error. - #[error("fatal error: {0}")] - Fatal(String), - /// A line could not be read from the geth stderr. - #[error("could not read line from geth stderr: {0}")] - ReadLineError(std::io::Error), - /// Genesis error - #[error("genesis error occurred: {0}")] - GenesisError(String), - /// Geth init error - #[error("geth init error occurred")] - InitError, - /// Spawn geth error - #[error("could not spawn geth: {0}")] - SpawnError(std::io::Error), - /// Wait error - #[error("could not wait for geth to exit: {0}")] - WaitError(std::io::Error), -} - /// Builder for launching `geth`. /// /// # Panics @@ -253,7 +202,7 @@ pub struct Geth { chain_id: Option, insecure_unlock: bool, genesis: Option, - mode: GethMode, + mode: NodeMode, clique_private_key: Option, } @@ -281,6 +230,21 @@ impl Geth { Self::new().path(path) } + /// Sets the `path` to the `geth` executable + /// + /// By default, it's expected that `geth` is in `$PATH`, see also + /// [`std::process::Command::new()`] + pub fn path>(mut self, path: T) -> Self { + self.program = Some(path.into()); + self + } + + /// Puts the `geth` instance in `dev` mode. + pub fn dev(mut self) -> Self { + self.mode = NodeMode::Dev(Default::default()); + self + } + /// Returns whether the node is launched in Clique consensus mode. pub const fn is_clique(&self) -> bool { self.clique_private_key.is_some() @@ -291,15 +255,6 @@ impl Geth { self.clique_private_key.as_ref().map(|pk| Address::from_public_key(pk.verifying_key())) } - /// Sets the `path` to the `geth` executable - /// - /// By default, it's expected that `geth` is in `$PATH`, see also - /// [`std::process::Command::new()`] - pub fn path>(mut self, path: T) -> Self { - self.program = Some(path.into()); - self - } - /// Sets the Clique Private Key to the `geth` executable, which will be later /// loaded on the node. /// @@ -326,13 +281,13 @@ impl Geth { /// options. pub fn p2p_port(mut self, port: u16) -> Self { match &mut self.mode { - GethMode::Dev(_) => { - self.mode = GethMode::NonDev(PrivateNetOptions { + NodeMode::Dev(_) => { + self.mode = NodeMode::NonDev(PrivateNetOptions { p2p_port: Some(port), ..Default::default() }) } - GethMode::NonDev(opts) => opts.p2p_port = Some(port), + NodeMode::NonDev(opts) => opts.p2p_port = Some(port), } self } @@ -342,7 +297,7 @@ impl Geth { /// This will put the geth instance in `dev` mode, discarding any previously set options that /// cannot be used in dev mode. pub const fn block_time(mut self, block_time: u64) -> Self { - self.mode = GethMode::Dev(DevOptions { block_time: Some(block_time) }); + self.mode = NodeMode::Dev(DevOptions { block_time: Some(block_time) }); self } @@ -375,11 +330,11 @@ impl Geth { fn inner_disable_discovery(&mut self) { match &mut self.mode { - GethMode::Dev(_) => { + NodeMode::Dev(_) => { self.mode = - GethMode::NonDev(PrivateNetOptions { discovery: false, ..Default::default() }) + NodeMode::NonDev(PrivateNetOptions { discovery: false, ..Default::default() }) } - GethMode::NonDev(opts) => opts.discovery = false, + NodeMode::NonDev(opts) => opts.discovery = false, } } @@ -423,14 +378,14 @@ impl Geth { } /// Consumes the builder and spawns `geth`. If spawning fails, returns an error. - pub fn try_spawn(mut self) -> Result { + pub fn try_spawn(mut self) -> Result { let bin_path = self .program .as_ref() .map_or_else(|| GETH.as_ref(), |bin| bin.as_os_str()) .to_os_string(); let mut cmd = Command::new(&bin_path); - // geth uses stderr for its logs + // `geth` uses stderr for its logs cmd.stderr(Stdio::piped()); // If no port provided, let the os chose it for us @@ -474,7 +429,7 @@ impl Geth { let clique_config = CliqueConfig { period: Some(0), epoch: Some(8) }; genesis.config.clique = Some(clique_config); - let clique_addr = clique_addr.ok_or(GethError::CliqueAddressError( + let clique_addr = clique_addr.ok_or(NodeError::CliqueAddressError( "could not calculates the address of the Clique consensus address.".to_string(), ))?; @@ -489,12 +444,12 @@ impl Geth { cmd.arg("--miner.etherbase").arg(format!("{clique_addr:?}")); } - let clique_addr = self.clique_address().ok_or(GethError::CliqueAddressError( + let clique_addr = self.clique_address().ok_or(NodeError::CliqueAddressError( "could not calculates the address of the Clique consensus address.".to_string(), ))?; self.genesis = Some(Genesis::clique_genesis( - self.chain_id.ok_or(GethError::ChainIdNotSet)?, + self.chain_id.ok_or(NodeError::ChainIdNotSet)?, clique_addr, )); @@ -506,19 +461,19 @@ impl Geth { if let Some(genesis) = &self.genesis { // create a temp dir to store the genesis file - let temp_genesis_dir_path = tempdir().map_err(GethError::CreateDirError)?.into_path(); + let temp_genesis_dir_path = tempdir().map_err(NodeError::CreateDirError)?.into_path(); // create a temp dir to store the genesis file let temp_genesis_path = temp_genesis_dir_path.join("genesis.json"); // create the genesis file let mut file = File::create(&temp_genesis_path).map_err(|_| { - GethError::GenesisError("could not create genesis file".to_string()) + NodeError::GenesisError("could not create genesis file".to_string()) })?; // serialize genesis and write to file serde_json::to_writer_pretty(&mut file, &genesis).map_err(|_| { - GethError::GenesisError("could not write genesis to file".to_string()) + NodeError::GenesisError("could not write genesis to file".to_string()) })?; let mut init_cmd = Command::new(bin_path); @@ -532,17 +487,17 @@ impl Geth { init_cmd.arg("init").arg(temp_genesis_path); let res = init_cmd .spawn() - .map_err(GethError::SpawnError)? + .map_err(NodeError::SpawnError)? .wait() - .map_err(GethError::WaitError)?; + .map_err(NodeError::WaitError)?; // .expect("failed to wait for geth init to exit"); if !res.success() { - return Err(GethError::InitError); + return Err(NodeError::InitError); } // clean up the temp dir which is now persisted std::fs::remove_dir_all(temp_genesis_dir_path).map_err(|_| { - GethError::GenesisError("could not remove genesis temp dir".to_string()) + NodeError::GenesisError("could not remove genesis temp dir".to_string()) })?; } @@ -551,20 +506,20 @@ impl Geth { // create the directory if it doesn't exist if !data_dir.exists() { - create_dir(data_dir).map_err(GethError::CreateDirError)?; + create_dir(data_dir).map_err(NodeError::CreateDirError)?; } } // Dev mode with custom block time let mut p2p_port = match self.mode { - GethMode::Dev(DevOptions { block_time }) => { + NodeMode::Dev(DevOptions { block_time }) => { cmd.arg("--dev"); if let Some(block_time) = block_time { cmd.arg("--dev.period").arg(block_time.to_string()); } None } - GethMode::NonDev(PrivateNetOptions { p2p_port, discovery }) => { + NodeMode::NonDev(PrivateNetOptions { p2p_port, discovery }) => { // if no port provided, let the os chose it for us let port = p2p_port.unwrap_or(0); cmd.arg("--port").arg(port.to_string()); @@ -588,31 +543,32 @@ impl Geth { cmd.arg("--ipcpath").arg(ipc); } - let mut child = cmd.spawn().map_err(GethError::SpawnError)?; + let mut child = cmd.spawn().map_err(NodeError::SpawnError)?; - let stderr = child.stderr.ok_or(GethError::NoStderr)?; + let stderr = child.stderr.take().ok_or(NodeError::NoStderr)?; let start = Instant::now(); let mut reader = BufReader::new(stderr); // we shouldn't need to wait for p2p to start if geth is in dev mode - p2p is disabled in // dev mode - let mut p2p_started = matches!(self.mode, GethMode::Dev(_)); - let mut http_started = false; + let mut p2p_started = matches!(self.mode, NodeMode::Dev(_)); + let mut ports_started = false; loop { - if start + GETH_STARTUP_TIMEOUT <= Instant::now() { - return Err(GethError::Timeout); + if start + NODE_STARTUP_TIMEOUT <= Instant::now() { + let _ = child.kill(); + return Err(NodeError::Timeout); } let mut line = String::with_capacity(120); - reader.read_line(&mut line).map_err(GethError::ReadLineError)?; + reader.read_line(&mut line).map_err(NodeError::ReadLineError)?; - if matches!(self.mode, GethMode::NonDev(_)) && line.contains("Started P2P networking") { + if matches!(self.mode, NodeMode::NonDev(_)) && line.contains("Started P2P networking") { p2p_started = true; } - if !matches!(self.mode, GethMode::Dev(_)) { + if !matches!(self.mode, NodeMode::Dev(_)) { // try to find the p2p port, if not in dev mode if line.contains("New local node record") { if let Some(port) = extract_value("tcp=", &line) { @@ -627,21 +583,23 @@ impl Geth { || (line.contains("HTTP server started") && !line.contains("auth=true")) { // Extracts the address from the output - if let Some(addr) = extract_endpoint(&line) { + if let Some(addr) = extract_endpoint("endpoint=", &line) { // use the actual http port port = addr.port(); } - http_started = true; + ports_started = true; } // Encountered an error such as Fatal: Error starting protocol stack: listen tcp // 127.0.0.1:8545: bind: address already in use if line.contains("Fatal:") { - return Err(GethError::Fatal(line)); + let _ = child.kill(); + return Err(NodeError::Fatal(line)); } - if p2p_started && http_started { + // If all ports have started we are ready to be queried. + if ports_started && p2p_started { break; } } @@ -654,43 +612,19 @@ impl Geth { ipc: self.ipc_path, data_dir: self.data_dir, p2p_port, + auth_port: self.authrpc_port, genesis: self.genesis, clique_private_key: self.clique_private_key, }) } } -// extracts the value for the given key and line -fn extract_value<'a>(key: &str, line: &'a str) -> Option<&'a str> { - let mut key = Cow::from(key); - if !key.ends_with('=') { - key = format!("{}=", key).into(); - } - line.find(key.as_ref()).map(|pos| { - let start = pos + key.len(); - let end = line[start..].find(' ').map(|i| start + i).unwrap_or(line.len()); - line[start..end].trim() - }) -} - -// extracts the value for the given key and line -fn extract_endpoint(line: &str) -> Option { - let val = extract_value("endpoint=", line)?; - val.parse::().ok() -} - -// These tests should use a different datadir for each `Geth` spawned +// These tests should use a different datadir for each `geth` spawned. #[cfg(test)] mod tests { use super::*; use std::path::Path; - #[test] - fn test_extract_address() { - let line = "INFO [07-01|13:20:42.774] HTTP server started endpoint=127.0.0.1:8545 auth=false prefix= cors= vhosts=localhost"; - assert_eq!(extract_endpoint(line), Some(SocketAddr::from(([127, 0, 0, 1], 8545)))); - } - #[test] fn port_0() { run_with_tempdir(|_| { diff --git a/crates/node-bindings/src/nodes/mod.rs b/crates/node-bindings/src/nodes/mod.rs new file mode 100644 index 00000000000..91d59734c3a --- /dev/null +++ b/crates/node-bindings/src/nodes/mod.rs @@ -0,0 +1,5 @@ +//! Bindings for various nodes. + +pub mod anvil; +pub mod geth; +pub mod reth; diff --git a/crates/node-bindings/src/nodes/reth.rs b/crates/node-bindings/src/nodes/reth.rs new file mode 100644 index 00000000000..70baa113f7f --- /dev/null +++ b/crates/node-bindings/src/nodes/reth.rs @@ -0,0 +1,542 @@ +//! Utilities for launching a Reth dev-mode instance. + +use crate::{extract_endpoint, NodeError, NodeInstanceError, NODE_STARTUP_TIMEOUT}; +use alloy_genesis::Genesis; +use std::{ + fs::create_dir, + io::{BufRead, BufReader}, + path::PathBuf, + process::{Child, ChildStdout, Command, Stdio}, + time::Instant, +}; +use url::Url; + +/// The exposed APIs +const API: &str = "eth,net,web3,txpool,trace,rpc,reth,ots,admin,debug"; + +/// The reth command +const RETH: &str = "reth"; + +/// A reth instance. Will close the instance when dropped. +/// +/// Construct this using [`Reth`]. +#[derive(Debug)] +pub struct RethInstance { + pid: Child, + http_port: u16, + ws_port: u16, + auth_port: Option, + p2p_port: Option, + ipc: Option, + data_dir: Option, + genesis: Option, +} + +impl RethInstance { + /// Returns the HTTP port of this instance + pub const fn http_port(&self) -> u16 { + self.http_port + } + + /// Returns the WS port of this instance + pub const fn ws_port(&self) -> u16 { + self.ws_port + } + + /// Returns the auth port of this instance + pub const fn auth_port(&self) -> Option { + self.auth_port + } + + /// Returns the p2p port of this instance + /// If discovery is disabled, this will be `None` + pub const fn p2p_port(&self) -> Option { + self.p2p_port + } + + /// Returns the HTTP endpoint of this instance + #[doc(alias = "http_endpoint")] + pub fn endpoint(&self) -> String { + format!("http://localhost:{}", self.http_port) + } + + /// Returns the Websocket endpoint of this instance + pub fn ws_endpoint(&self) -> String { + format!("ws://localhost:{}", self.ws_port) + } + + /// Returns the IPC endpoint of this instance + pub fn ipc_endpoint(&self) -> String { + self.ipc.clone().map_or_else(|| "reth.ipc".to_string(), |ipc| ipc.display().to_string()) + } + + /// Returns the HTTP endpoint url of this instance + #[doc(alias = "http_endpoint_url")] + pub fn endpoint_url(&self) -> Url { + Url::parse(&self.endpoint()).unwrap() + } + + /// Returns the Websocket endpoint url of this instance + pub fn ws_endpoint_url(&self) -> Url { + Url::parse(&self.ws_endpoint()).unwrap() + } + + /// Returns the path to this instances' data directory + pub const fn data_dir(&self) -> &Option { + &self.data_dir + } + + /// Returns the genesis configuration used to configure this instance + pub const fn genesis(&self) -> &Option { + &self.genesis + } + + /// Takes the stdout contained in the child process. + /// + /// This leaves a `None` in its place, so calling methods that require a stdout to be present + /// will fail if called after this. + pub fn stdout(&mut self) -> Result { + self.pid.stdout.take().ok_or(NodeInstanceError::NoStdout) + } +} + +impl Drop for RethInstance { + fn drop(&mut self) { + self.pid.kill().expect("could not kill reth"); + } +} + +/// Builder for launching `reth`. +/// +/// # Panics +/// +/// If `spawn` is called without `reth` being available in the user's $PATH +/// +/// # Example +/// +/// ```no_run +/// use alloy_node_bindings::Reth; +/// +/// let port = 8545u16; +/// let url = format!("http://localhost:{}", port).to_string(); +/// +/// let reth = Reth::new().instance(0).block_time("12sec").spawn(); +/// +/// drop(reth); // this will kill the instance +/// ``` +#[derive(Clone, Debug, Default)] +#[must_use = "This Builder struct does nothing unless it is `spawn`ed"] +pub struct Reth { + dev: bool, + block_time: Option, + instance: u16, + discovery_enabled: bool, + program: Option, + ipc_path: Option, + ipc_enabled: bool, + data_dir: Option, + chain_or_path: Option, + genesis: Option, +} + +impl Reth { + /// Creates an empty Reth builder. + /// + /// The mnemonic is chosen randomly. + pub const fn new() -> Self { + Self { + dev: false, + block_time: None, + instance: 0, + discovery_enabled: true, + program: None, + ipc_path: None, + ipc_enabled: false, + data_dir: None, + chain_or_path: None, + genesis: None, + } + } + + /// Creates a Reth builder which will execute `reth` at the given path. + /// + /// # Example + /// + /// ``` + /// use alloy_node_bindings::Reth; + /// # fn a() { + /// let reth = Reth::at("../reth/target/release/reth").spawn(); + /// + /// println!("Reth running at `{}`", reth.endpoint()); + /// # } + /// ``` + pub fn at(path: impl Into) -> Self { + Self::new().path(path) + } + + /// Sets the `path` to the `reth` executable + /// + /// By default, it's expected that `reth` is in `$PATH`, see also + /// [`std::process::Command::new()`] + pub fn path>(mut self, path: T) -> Self { + self.program = Some(path.into()); + self + } + + /// Enable `dev` mode for the reth instance. + pub const fn dev(mut self) -> Self { + self.dev = true; + self + } + + /// Sets the block time for the reth instance. + /// Parses strings using + /// This is only used if `dev` mode is enabled. + pub fn block_time(mut self, block_time: &str) -> Self { + self.block_time = Some(block_time.to_string()); + self + } + + /// Disables discovery for the reth instance. + pub const fn disable_discovery(mut self) -> Self { + self.discovery_enabled = false; + self + } + + /// Sets the chain id for the reth instance. + pub fn chain_or_path(mut self, chain_or_path: &str) -> Self { + self.chain_or_path = Some(chain_or_path.to_string()); + self + } + + /// Enable IPC for the reth instance. + pub const fn enable_ipc(mut self) -> Self { + self.ipc_enabled = true; + self + } + + /// Sets the instance number for the reth instance. + pub const fn instance(mut self, instance: u16) -> Self { + self.instance = instance; + self + } + + /// Sets the IPC path for the socket. + pub fn ipc_path>(mut self, path: T) -> Self { + self.ipc_path = Some(path.into()); + self + } + + /// Sets the data directory for reth. + pub fn data_dir>(mut self, path: T) -> Self { + self.data_dir = Some(path.into()); + self + } + + /// Sets the `genesis.json` for the reth instance. + /// + /// If this is set, reth will be initialized with `reth init` and the `--datadir` option will be + /// set to the same value as `data_dir`. + /// + /// This is destructive and will overwrite any existing data in the data directory. + pub fn genesis(mut self, genesis: Genesis) -> Self { + self.genesis = Some(genesis); + self + } + + /// Consumes the builder and spawns `reth`. + /// + /// # Panics + /// + /// If spawning the instance fails at any point. + #[track_caller] + pub fn spawn(self) -> RethInstance { + self.try_spawn().unwrap() + } + + /// Consumes the builder and spawns `reth`. If spawning fails, returns an error. + pub fn try_spawn(self) -> Result { + let bin_path = self + .program + .as_ref() + .map_or_else(|| RETH.as_ref(), |bin| bin.as_os_str()) + .to_os_string(); + let mut cmd = Command::new(&bin_path); + // `reth` uses stdout for its logs + cmd.stdout(Stdio::piped()); + + // Use Reth's `node` subcommand. + cmd.arg("node"); + + // If the `dev` flag is set, enable it. + if self.dev { + // Enable the dev mode. + // This mode uses a local proof-of-authority consensus engine with either fixed block + // times or automatically mined blocks. + // Disables network discovery and enables local http server. + // Prefunds 20 accounts derived by mnemonic "test test test test test test test test + // test test test junk" with 10 000 ETH each. + cmd.arg("--dev"); + + // If the block time is set, use it. + if let Some(block_time) = self.block_time { + cmd.arg("--dev.block-time").arg(block_time); + } + } + + // If IPC is not enabled on the builder, disable it. + if !self.ipc_enabled { + cmd.arg("--ipcdisable"); + } + + // Open the HTTP API. + cmd.arg("--http"); + cmd.arg("--http.api").arg(API); + + // Open the WS API. + cmd.arg("--ws"); + cmd.arg("--ws.api").arg(API); + + // Configure the IPC path if it is set. + if let Some(ipc) = &self.ipc_path { + cmd.arg("--ipcpath").arg(ipc); + } + + // Configures the ports of the node to avoid conflicts with the defaults. This is useful for + // running multiple nodes on the same machine. + // + // Changes to the following port numbers: + // - `DISCOVERY_PORT`: default + `instance` - 1 + // - `AUTH_PORT`: default + `instance` * 100 - 100 + // - `HTTP_RPC_PORT`: default - `instance` + 1 + // - `WS_RPC_PORT`: default + `instance` * 2 - 2 + if self.instance > 0 { + cmd.arg("--instance").arg(self.instance.to_string()); + } + + if let Some(data_dir) = &self.data_dir { + cmd.arg("--datadir").arg(data_dir); + + // create the directory if it doesn't exist + if !data_dir.exists() { + create_dir(data_dir).map_err(NodeError::CreateDirError)?; + } + } + + if !self.discovery_enabled { + cmd.arg("--disable-discovery"); + cmd.arg("--no-persist-peers"); + } else { + // Verbosity is required to read the P2P port from the logs. + cmd.arg("--verbosity").arg("-vvv"); + } + + if let Some(chain_or_path) = self.chain_or_path { + cmd.arg("--chain").arg(chain_or_path); + } + + // Disable color output to make parsing logs easier. + cmd.arg("--color").arg("never"); + + let mut child = cmd.spawn().map_err(NodeError::SpawnError)?; + + let stdout = child.stdout.take().ok_or(NodeError::NoStdout)?; + + let start = Instant::now(); + let mut reader = BufReader::new(stdout); + + let mut http_port = 0; + let mut ws_port = 0; + let mut auth_port = 0; + let mut p2p_port = 0; + + let mut ports_started = false; + let mut p2p_started = !self.discovery_enabled; + + loop { + if start + NODE_STARTUP_TIMEOUT <= Instant::now() { + let _ = child.kill(); + return Err(NodeError::Timeout); + } + + let mut line = String::with_capacity(120); + reader.read_line(&mut line).map_err(NodeError::ReadLineError)?; + + if line.contains("RPC HTTP server started") { + if let Some(addr) = extract_endpoint("url=", &line) { + http_port = addr.port(); + } + } + + if line.contains("RPC WS server started") { + if let Some(addr) = extract_endpoint("url=", &line) { + ws_port = addr.port(); + } + } + + if line.contains("RPC auth server started") { + if let Some(addr) = extract_endpoint("url=", &line) { + auth_port = addr.port(); + } + } + + // Encountered a critical error, exit early. + if line.contains("ERROR") { + let _ = child.kill(); + return Err(NodeError::Fatal(line)); + } + + if http_port != 0 && ws_port != 0 && auth_port != 0 { + ports_started = true; + } + + if self.discovery_enabled { + if line.contains("Updated local ENR") { + if let Some(port) = extract_endpoint("IpV4 UDP Socket", &line) { + p2p_port = port.port(); + p2p_started = true; + } + } + } else { + p2p_started = true; + } + + // If all ports have started we are ready to be queried. + if ports_started && p2p_started { + break; + } + } + + child.stdout = Some(reader.into_inner()); + + Ok(RethInstance { + pid: child, + http_port, + ws_port, + p2p_port: if p2p_port != 0 { Some(p2p_port) } else { None }, + ipc: self.ipc_path, + data_dir: self.data_dir, + auth_port: Some(auth_port), + genesis: self.genesis, + }) + } +} + +// These tests should use a different datadir for each `reth` instance spawned. +#[cfg(test)] +mod tests { + use super::*; + use std::path::Path; + + #[test] + #[cfg(not(windows))] + fn can_launch_reth() { + run_with_tempdir(|temp_dir_path| { + let reth = Reth::new().data_dir(temp_dir_path).spawn(); + + assert_ports(&reth, false); + }); + } + + #[test] + #[cfg(not(windows))] + fn can_launch_reth_sepolia() { + run_with_tempdir(|temp_dir_path| { + let reth = Reth::new().chain_or_path("sepolia").data_dir(temp_dir_path).spawn(); + + assert_ports(&reth, false); + }); + } + + #[test] + #[cfg(not(windows))] + fn can_launch_reth_dev() { + run_with_tempdir(|temp_dir_path| { + let reth = Reth::new().dev().disable_discovery().data_dir(temp_dir_path).spawn(); + + assert_ports(&reth, true); + }); + } + + #[test] + #[cfg(not(windows))] + fn can_launch_reth_dev_custom_genesis() { + run_with_tempdir(|temp_dir_path| { + let reth = Reth::new() + .dev() + .disable_discovery() + .data_dir(temp_dir_path) + .genesis(Genesis::default()) + .spawn(); + + assert_ports(&reth, true); + }); + } + + #[test] + #[cfg(not(windows))] + fn can_launch_reth_dev_custom_blocktime() { + run_with_tempdir(|temp_dir_path| { + let reth = Reth::new() + .dev() + .disable_discovery() + .block_time("1sec") + .data_dir(temp_dir_path) + .spawn(); + + assert_ports(&reth, true); + }); + } + + #[test] + #[cfg(not(windows))] + fn can_launch_reth_p2p_instance1() { + run_with_tempdir(|temp_dir_path| { + let reth = Reth::new().instance(1).data_dir(temp_dir_path).spawn(); + + assert_eq!(reth.http_port(), 8545); + assert_eq!(reth.ws_port(), 8546); + assert_eq!(reth.auth_port(), Some(8551)); + assert_eq!(reth.p2p_port(), Some(30303)); + }); + } + + #[test] + #[cfg(not(windows))] + fn can_launch_reth_p2p_instance2() { + run_with_tempdir(|temp_dir_path| { + let reth = Reth::new().instance(2).data_dir(temp_dir_path).spawn(); + + assert_eq!(reth.http_port(), 8544); + assert_eq!(reth.ws_port(), 8548); + assert_eq!(reth.auth_port(), Some(8651)); + assert_eq!(reth.p2p_port(), Some(30304)); + }); + } + + /// Allows running tests with a temporary directory, which is cleaned up after the function is + /// called. + /// + /// Helps with tests that spawn a helper instance, which has to be dropped before the temporary + /// directory is cleaned up. + #[track_caller] + fn run_with_tempdir(f: impl Fn(&Path)) { + let temp_dir = tempfile::tempdir().unwrap(); + let temp_dir_path = temp_dir.path(); + f(temp_dir_path); + temp_dir.close().unwrap(); + } + + // Asserts that the ports are set correctly for the given reth instance. + fn assert_ports(reth: &RethInstance, dev: bool) { + assert_eq!(reth.http_port(), 8545); + assert_eq!(reth.ws_port(), 8546); + assert_eq!(reth.auth_port(), Some(8551)); + + if dev { + assert_eq!(reth.p2p_port(), None); + } else { + assert_eq!(reth.p2p_port(), Some(30303)); + } + } +} diff --git a/crates/node-bindings/src/utils.rs b/crates/node-bindings/src/utils.rs new file mode 100644 index 00000000000..11c52e1e3f7 --- /dev/null +++ b/crates/node-bindings/src/utils.rs @@ -0,0 +1,87 @@ +//! Utility functions for the node bindings. + +use std::{ + borrow::Cow, + net::{SocketAddr, TcpListener}, +}; + +/// A bit of hack to find an unused TCP port. +/// +/// Does not guarantee that the given port is unused after the function exists, just that it was +/// unused before the function started (i.e., it does not reserve a port). +pub(crate) fn unused_port() -> u16 { + let listener = TcpListener::bind("127.0.0.1:0") + .expect("Failed to create TCP listener to find unused port"); + + let local_addr = + listener.local_addr().expect("Failed to read TCP listener local_addr to find unused port"); + local_addr.port() +} + +/// Extracts the value for the given key from the line of text. +/// It supports keys that end with '=' or ': '. +pub(crate) fn extract_value<'a>(key: &str, line: &'a str) -> Option<&'a str> { + let mut key_equal = Cow::from(key); + let mut key_colon = Cow::from(key); + + // Prepare both key variants + if !key_equal.ends_with('=') { + key_equal = format!("{}=", key).into(); + } + if !key_colon.ends_with(": ") { + key_colon = format!("{}: ", key).into(); + } + + // Try to find the key with '=' + if let Some(pos) = line.find(key_equal.as_ref()) { + let start = pos + key_equal.len(); + let end = line[start..].find(' ').map(|i| start + i).unwrap_or(line.len()); + if start <= line.len() && end <= line.len() { + return Some(line[start..end].trim()); + } + } + + // If not found, try to find the key with ': ' + if let Some(pos) = line.find(key_colon.as_ref()) { + let start = pos + key_colon.len(); + let end = line[start..].find(',').unwrap_or(line.len()); // Assuming comma or end of line + if start <= line.len() && start + end <= line.len() { + return Some(line[start..start + end].trim()); + } + } + + // If neither variant matches, return None + None +} + +/// Extracts the endpoint from the given line. +pub(crate) fn extract_endpoint(key: &str, line: &str) -> Option { + let val = extract_value(key, line)?; + + // Remove the "Some( ... )" wrapper if it exists + let val = + if val.starts_with("Some(") && val.ends_with(')') { &val[5..val.len() - 1] } else { val }; + + val.parse::().ok() +} + +#[test] +fn test_extract_http_address() { + let line = "INFO [07-01|13:20:42.774] HTTP server started endpoint=127.0.0.1:8545 auth=false prefix= cors= vhosts=localhost"; + assert_eq!(extract_endpoint("endpoint=", line), Some(SocketAddr::from(([127, 0, 0, 1], 8545)))); +} + +#[test] +fn test_extract_udp_address() { + let line = "Updated local ENR enr=Enr { id: Some(\"v4\"), seq: 2, NodeId: 0x04dad428038b4db230fc5298646e137564fc6861662f32bdbf220f31299bdde7, signature: \"416520d69bfd701d95f4b77778970a5c18fa86e4dd4dc0746e80779d986c68605f491c01ef39cd3739fdefc1e3558995ad2f5d325f9e1db795896799e8ee94a3\", IpV4 UDP Socket: Some(0.0.0.0:30303), IpV6 UDP Socket: None, IpV4 TCP Socket: Some(0.0.0.0:30303), IpV6 TCP Socket: None, Other Pairs: [(\"eth\", \"c984fc64ec0483118c30\"), (\"secp256k1\", \"a103aa181e8fd5df651716430f1d4b504b54d353b880256f56aa727beadd1b7a9766\")], .. }"; + assert_eq!( + extract_endpoint("IpV4 TCP Socket: ", line), + Some(SocketAddr::from(([0, 0, 0, 0], 30303))) + ); +} + +#[test] +fn test_unused_port() { + let port = unused_port(); + assert!(port > 0); +} From ab630b8029c5b0fa61d5f2cb9a00be24a56e585a Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Thu, 5 Sep 2024 18:03:06 +0200 Subject: [PATCH 138/186] chore(eip1898): display `RpcBlockHash` (#1242) * Impl display for alloy_eips::eip1898::RpcBlockHash * Add test for display RpcBlockHash * Impl display for alloy_eips::eip1898::BlockId * Add test for display BlockId --- crates/eips/src/eip1898.rs | 90 +++++++++++++++++++++++++++++++++++++- 1 file changed, 89 insertions(+), 1 deletion(-) diff --git a/crates/eips/src/eip1898.rs b/crates/eips/src/eip1898.rs index f7c02b16986..16e054573bc 100644 --- a/crates/eips/src/eip1898.rs +++ b/crates/eips/src/eip1898.rs @@ -56,6 +56,16 @@ impl AsRef for RpcBlockHash { } } +impl Display for RpcBlockHash { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + let Self { block_hash, require_canonical } = self; + if *require_canonical == Some(true) { + write!(f, "canonical ")? + } + write!(f, "hash {}", block_hash) + } +} + /// A block Number (or tag - "latest", "earliest", "pending") #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)] pub enum BlockNumberOrTag { @@ -515,6 +525,20 @@ impl<'de> Deserialize<'de> for BlockId { } } +impl Display for BlockId { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self { + Self::Hash(hash) => write!(f, "{}", hash), + Self::Number(num) => { + if num.is_number() { + return write!(f, "number {}", num); + } + write!(f, "{}", num) + } + } + } +} + /// Error thrown when parsing a [BlockId] from a string. #[derive(Debug)] pub enum ParseBlockIdError { @@ -757,11 +781,16 @@ impl FromStr for BlockHashOrNumber { } } -#[cfg(all(test, feature = "serde"))] +#[cfg(test)] mod tests { + use alloy_primitives::b256; + use super::*; + const HASH: B256 = b256!("1a15e3c30cf094a99826869517b16d185d45831d3a494f01030b0001a9d3ebb9"); + #[test] + #[cfg(feature = "serde")] fn compact_block_number_serde() { let num: BlockNumberOrTag = 1u64.into(); let serialized = serde_json::to_string(&num).unwrap(); @@ -781,6 +810,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn can_parse_eip1898_block_ids() { let num = serde_json::json!( { "blockNumber": "0x0" } @@ -856,4 +886,62 @@ mod tests { ) ); } + + #[test] + fn display_rpc_block_hash() { + let hash = RpcBlockHash::from_hash(HASH, Some(true)); + + assert_eq!( + hash.to_string(), + "canonical hash 0x1a15e3c30cf094a99826869517b16d185d45831d3a494f01030b0001a9d3ebb9" + ); + + let hash = RpcBlockHash::from_hash(HASH, None); + + assert_eq!( + hash.to_string(), + "hash 0x1a15e3c30cf094a99826869517b16d185d45831d3a494f01030b0001a9d3ebb9" + ); + } + + #[test] + fn display_block_id() { + let id = BlockId::hash(HASH); + + assert_eq!( + id.to_string(), + "hash 0x1a15e3c30cf094a99826869517b16d185d45831d3a494f01030b0001a9d3ebb9" + ); + + let id = BlockId::hash_canonical(HASH); + + assert_eq!( + id.to_string(), + "canonical hash 0x1a15e3c30cf094a99826869517b16d185d45831d3a494f01030b0001a9d3ebb9" + ); + + let id = BlockId::number(100000); + + assert_eq!(id.to_string(), "number 0x186a0"); + + let id = BlockId::latest(); + + assert_eq!(id.to_string(), "latest"); + + let id = BlockId::safe(); + + assert_eq!(id.to_string(), "safe"); + + let id = BlockId::finalized(); + + assert_eq!(id.to_string(), "finalized"); + + let id = BlockId::earliest(); + + assert_eq!(id.to_string(), "earliest"); + + let id = BlockId::pending(); + + assert_eq!(id.to_string(), "pending"); + } } From 37b0c294a2baa5e2ead36259f9b5c7d9a000ad7c Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Fri, 6 Sep 2024 17:13:55 +0530 Subject: [PATCH 139/186] feat(rpc-types-eth): AnyBlock (#1243) * feat(rpc-types-eth): AnyBlock * rename to AnyNetworkBlock --- crates/rpc-types-eth/src/lib.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/crates/rpc-types-eth/src/lib.rs b/crates/rpc-types-eth/src/lib.rs index 27b58ae63be..14e020683df 100644 --- a/crates/rpc-types-eth/src/lib.rs +++ b/crates/rpc-types-eth/src/lib.rs @@ -14,6 +14,11 @@ pub use account::*; mod block; pub use block::*; +use alloy_serde::WithOtherFields; + +/// A catch-all block type for handling blocks on multiple networks. +pub type AnyNetworkBlock = WithOtherFields>>; + pub use alloy_network_primitives::{ BlockTransactionHashes, BlockTransactions, BlockTransactionsKind, }; From ad0538b48db9f2ae8dad5e8c9cfc6df0c5e620e2 Mon Sep 17 00:00:00 2001 From: refcell Date: Fri, 6 Sep 2024 16:17:14 -0400 Subject: [PATCH 140/186] fix(consensus): Remove Unused Alloc Vecs (#1250) * fix(consensus): remove unused alloc Vecs * fix: updates and msrv * fix: serde tests --- .github/workflows/ci.yml | 10 +++++----- Cargo.toml | 2 +- clippy.toml | 2 +- crates/consensus/src/transaction/envelope.rs | 2 -- crates/consensus/src/transaction/typed.rs | 3 --- crates/rpc-types-eth/src/transaction/mod.rs | 4 ++-- 6 files changed, 9 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8a4eff4a4e7..645acbc53a7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,7 +24,7 @@ jobs: rust: - "stable" - "nightly" - - "1.78" # MSRV + - "1.79" # MSRV flags: # No features - "--no-default-features" @@ -34,7 +34,7 @@ jobs: - "--all-features" exclude: # All features on MSRV - - rust: "1.78" # MSRV + - rust: "1.79" # MSRV flags: "--all-features" steps: - uses: actions/checkout@v4 @@ -53,14 +53,14 @@ jobs: cache-on-failure: true # Only run tests on latest stable and above - name: Install cargo-nextest - if: ${{ matrix.rust != '1.78' }} # MSRV + if: ${{ matrix.rust != '1.79' }} # MSRV uses: taiki-e/install-action@nextest - name: build - if: ${{ matrix.rust == '1.78' }} # MSRV + if: ${{ matrix.rust == '1.79' }} # MSRV run: cargo build --workspace ${{ matrix.flags }} - name: test shell: bash - if: ${{ matrix.rust != '1.78' }} # MSRV + if: ${{ matrix.rust != '1.79' }} # MSRV run: cargo nextest run --workspace ${{ matrix.flags }} doctest: diff --git a/Cargo.toml b/Cargo.toml index bca3ffc4c47..65955d7f263 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ resolver = "2" [workspace.package] version = "0.3.1" edition = "2021" -rust-version = "1.78" +rust-version = "1.79" authors = ["Alloy Contributors"] license = "MIT OR Apache-2.0" homepage = "https://github.com/alloy-rs/alloy" diff --git a/clippy.toml b/clippy.toml index 0c4f17e6aea..f1acf4b1122 100644 --- a/clippy.toml +++ b/clippy.toml @@ -1 +1 @@ -msrv = "1.78" +msrv = "1.79" diff --git a/crates/consensus/src/transaction/envelope.rs b/crates/consensus/src/transaction/envelope.rs index 79ab90b9e15..fc5c324e983 100644 --- a/crates/consensus/src/transaction/envelope.rs +++ b/crates/consensus/src/transaction/envelope.rs @@ -1,5 +1,3 @@ -#[cfg(not(feature = "std"))] -use alloc::vec::Vec; use core::fmt; use crate::{Signed, Transaction, TxEip1559, TxEip2930, TxEip7702, TxLegacy}; diff --git a/crates/consensus/src/transaction/typed.rs b/crates/consensus/src/transaction/typed.rs index 3023fc7bdac..0dca9ebb2d5 100644 --- a/crates/consensus/src/transaction/typed.rs +++ b/crates/consensus/src/transaction/typed.rs @@ -1,6 +1,3 @@ -#[cfg(not(feature = "std"))] -use alloc::vec::Vec; - use alloy_eips::{eip2930::AccessList, eip7702::SignedAuthorization}; use alloy_primitives::{ChainId, TxKind, B256}; diff --git a/crates/rpc-types-eth/src/transaction/mod.rs b/crates/rpc-types-eth/src/transaction/mod.rs index 1624bd21656..6d6262cdd0f 100644 --- a/crates/rpc-types-eth/src/transaction/mod.rs +++ b/crates/rpc-types-eth/src/transaction/mod.rs @@ -373,7 +373,7 @@ mod tests { let serialized = serde_json::to_string(&transaction).unwrap(); assert_eq!( serialized, - r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000001","nonce":"0x2","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000003","blockNumber":"0x4","transactionIndex":"0x5","from":"0x0000000000000000000000000000000000000006","to":"0x0000000000000000000000000000000000000007","value":"0x8","gasPrice":"0x9","gas":"0xa","maxFeePerGas":"0x15","maxPriorityFeePerGas":"0x16","input":"0x0b0c0d","r":"0xe","s":"0xe","v":"0xe","chainId":"0x11","type":"0x14","authorizationList":[{"chainId":"0x1","address":"0x0000000000000000000000000000000000000006","nonce":"0x1","r":"0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353","s":"0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","v":27}]}"# + r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000001","nonce":"0x2","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000003","blockNumber":"0x4","transactionIndex":"0x5","from":"0x0000000000000000000000000000000000000006","to":"0x0000000000000000000000000000000000000007","value":"0x8","gasPrice":"0x9","gas":"0xa","maxFeePerGas":"0x15","maxPriorityFeePerGas":"0x16","input":"0x0b0c0d","r":"0xe","s":"0xe","v":"0xe","chainId":"0x11","type":"0x14","authorizationList":[{"chainId":"0x1","address":"0x0000000000000000000000000000000000000006","nonce":"0x1","r":"0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353","s":"0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","v":"0x1b"}]}"# ); let deserialized: Transaction = serde_json::from_str(&serialized).unwrap(); assert_eq!(transaction, deserialized); @@ -416,7 +416,7 @@ mod tests { let serialized = serde_json::to_string(&transaction).unwrap(); assert_eq!( serialized, - r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000001","nonce":"0x2","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000003","blockNumber":"0x4","transactionIndex":"0x5","from":"0x0000000000000000000000000000000000000006","to":"0x0000000000000000000000000000000000000007","value":"0x8","gasPrice":"0x9","gas":"0xa","maxFeePerGas":"0x15","maxPriorityFeePerGas":"0x16","input":"0x0b0c0d","r":"0xe","s":"0xe","v":"0xe","yParity":"0x1","chainId":"0x11","type":"0x14","authorizationList":[{"chainId":"0x1","address":"0x0000000000000000000000000000000000000006","nonce":"0x1","r":"0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353","s":"0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","v":27}]}"# + r#"{"hash":"0x0000000000000000000000000000000000000000000000000000000000000001","nonce":"0x2","blockHash":"0x0000000000000000000000000000000000000000000000000000000000000003","blockNumber":"0x4","transactionIndex":"0x5","from":"0x0000000000000000000000000000000000000006","to":"0x0000000000000000000000000000000000000007","value":"0x8","gasPrice":"0x9","gas":"0xa","maxFeePerGas":"0x15","maxPriorityFeePerGas":"0x16","input":"0x0b0c0d","r":"0xe","s":"0xe","v":"0xe","yParity":"0x1","chainId":"0x11","type":"0x14","authorizationList":[{"chainId":"0x1","address":"0x0000000000000000000000000000000000000006","nonce":"0x1","r":"0x48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353","s":"0xefffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804","v":"0x1b"}]}"# ); let deserialized: Transaction = serde_json::from_str(&serialized).unwrap(); assert_eq!(transaction, deserialized); From 122c4b187af3c621bdd10f829d44538300c0dae0 Mon Sep 17 00:00:00 2001 From: refcell Date: Fri, 6 Sep 2024 17:58:02 -0400 Subject: [PATCH 141/186] feat: no_std network primitives (#1248) --- .github/workflows/no_std.yml | 2 +- Cargo.toml | 2 +- README.md | 2 +- crates/network-primitives/Cargo.toml | 4 ++++ crates/network-primitives/src/block.rs | 12 ++++++++---- crates/network-primitives/src/lib.rs | 3 +++ crates/rpc-types-eth/Cargo.toml | 4 ++-- 7 files changed, 20 insertions(+), 9 deletions(-) diff --git a/.github/workflows/no_std.yml b/.github/workflows/no_std.yml index 9d16d58084d..b9af136c279 100644 --- a/.github/workflows/no_std.yml +++ b/.github/workflows/no_std.yml @@ -16,7 +16,7 @@ jobs: strategy: fail-fast: false matrix: - crate: ["alloy-eips", "alloy-consensus", "alloy-genesis"] + crate: ["alloy-eips", "alloy-consensus", "alloy-genesis", "alloy-network-primitives"] steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable diff --git a/Cargo.toml b/Cargo.toml index 65955d7f263..f016321c610 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -124,7 +124,7 @@ auto_impl = "1.2" base64 = "0.22" bimap = "0.6" home = "0.5" -itertools = "0.13" +itertools = { version = "0.13", default-features = false } once_cell = { version = "1.19", default-features = false } pin-project = "1.1" rand = "0.8" diff --git a/README.md b/README.md index cde535f8cb7..c3eeecec195 100644 --- a/README.md +++ b/README.md @@ -124,7 +124,7 @@ When updating this, also update: - .github/workflows/ci.yml --> -The current MSRV (minimum supported rust version) is 1.78. +The current MSRV (minimum supported rust version) is 1.79. Alloy will keep a rolling MSRV policy of **at least** two versions behind the latest stable release (so if the latest stable release is 1.58, we would diff --git a/crates/network-primitives/Cargo.toml b/crates/network-primitives/Cargo.toml index a56fb3e6239..bd107082ef3 100644 --- a/crates/network-primitives/Cargo.toml +++ b/crates/network-primitives/Cargo.toml @@ -26,3 +26,7 @@ serde.workspace = true [dev-dependencies] rand.workspace = true + +[features] +default = ["std"] +std = ["alloy-primitives/std"] diff --git a/crates/network-primitives/src/block.rs b/crates/network-primitives/src/block.rs index 1ec52f338ba..f817d2988b9 100644 --- a/crates/network-primitives/src/block.rs +++ b/crates/network-primitives/src/block.rs @@ -1,6 +1,9 @@ use alloy_primitives::B256; use serde::{Deserialize, Serialize}; +use alloc::{vec, vec::Vec}; +use core::slice; + use crate::TransactionResponse; /// Block Transactions depending on the boolean attribute of `eth_getBlockBy*`, @@ -69,10 +72,10 @@ impl BlockTransactions { /// Returns an iterator over the transactions (if any). This will be empty if the block is not /// full. - pub fn into_transactions(self) -> std::vec::IntoIter { + pub fn into_transactions(self) -> vec::IntoIter { match self { Self::Full(txs) => txs.into_iter(), - _ => std::vec::IntoIter::default(), + _ => vec::IntoIter::default(), } } @@ -149,8 +152,8 @@ pub struct BlockTransactionHashes<'a, T>(BlockTransactionHashesInner<'a, T>); #[derive(Clone, Debug)] enum BlockTransactionHashesInner<'a, T> { - Hashes(std::slice::Iter<'a, B256>), - Full(std::slice::Iter<'a, T>), + Hashes(slice::Iter<'a, B256>), + Full(slice::Iter<'a, T>), Uncle, } @@ -209,6 +212,7 @@ impl DoubleEndedIterator for BlockTransactionHashes<'_, } } +#[cfg(feature = "std")] impl<'a, T: TransactionResponse> std::iter::FusedIterator for BlockTransactionHashes<'a, T> {} /// Determines how the `transactions` field of block should be filled. diff --git a/crates/network-primitives/src/lib.rs b/crates/network-primitives/src/lib.rs index d1534307e4a..6012668a3dd 100644 --- a/crates/network-primitives/src/lib.rs +++ b/crates/network-primitives/src/lib.rs @@ -5,6 +5,9 @@ )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate alloc; mod traits; pub use traits::{BlockResponse, HeaderResponse, ReceiptResponse, TransactionResponse}; diff --git a/crates/rpc-types-eth/Cargo.toml b/crates/rpc-types-eth/Cargo.toml index 1d40c304c78..e1f36e74051 100644 --- a/crates/rpc-types-eth/Cargo.toml +++ b/crates/rpc-types-eth/Cargo.toml @@ -23,8 +23,8 @@ alloy-rlp = { workspace = true, features = ["arrayvec", "derive"] } alloy-primitives = { workspace = true, features = ["rlp", "serde", "std"] } alloy-serde.workspace = true -alloy-consensus = { workspace = true, features = ["std", "serde"] } -alloy-eips = { workspace = true, features = ["std", "serde"] } +alloy-consensus = { workspace = true, features = ["serde", "std"] } +alloy-eips = { workspace = true, features = ["serde", "std"] } alloy-network-primitives.workspace = true From 9627e0af5cc38c6c9deecc548e94f8d5b3f4e88d Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Sat, 7 Sep 2024 05:08:54 -0700 Subject: [PATCH 142/186] dep: bump tower to 0.5 (#1249) * dep: bump tower to 0.5 * fix clippy --- Cargo.toml | 2 +- crates/rpc-client/src/client.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f016321c610..ef88a7a5862 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -113,7 +113,7 @@ rustls = { version = "0.23", default-features = false, features = [ ] } tokio-test = "0.4" tokio-tungstenite = "0.23" -tower = { version = "0.4", features = ["util"] } +tower = { version = "0.5", features = ["util"] } # tracing tracing = "0.1" diff --git a/crates/rpc-client/src/client.rs b/crates/rpc-client/src/client.rs index b960239e35e..370d18ccaa6 100644 --- a/crates/rpc-client/src/client.rs +++ b/crates/rpc-client/src/client.rs @@ -39,7 +39,7 @@ impl Clone for RpcClient { impl RpcClient { /// Create a new [`ClientBuilder`]. - pub fn builder() -> ClientBuilder { + pub const fn builder() -> ClientBuilder { ClientBuilder { builder: ServiceBuilder::new() } } } From 24431011b884ca92dfc3ee37f9dfae9697ee2a28 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Sat, 7 Sep 2024 06:55:26 -0700 Subject: [PATCH 143/186] rpc: add getter trait methods to `ReceiptResponse` (#1251) * rpc: Add getter trait methods to ReceiptResponse * fix no std * fix comments * 7702 docs --------- Co-authored-by: Matthias Seitz --- crates/network-primitives/Cargo.toml | 1 + crates/network-primitives/src/traits.rs | 67 +++++++++++++++++++ .../rpc-types-eth/src/transaction/receipt.rs | 40 ++++++++++- 3 files changed, 106 insertions(+), 2 deletions(-) diff --git a/crates/network-primitives/Cargo.toml b/crates/network-primitives/Cargo.toml index bd107082ef3..32447e59121 100644 --- a/crates/network-primitives/Cargo.toml +++ b/crates/network-primitives/Cargo.toml @@ -21,6 +21,7 @@ workspace = true [dependencies] alloy-primitives.workspace = true alloy-serde.workspace = true +alloy-eips.workspace = true serde.workspace = true diff --git a/crates/network-primitives/src/traits.rs b/crates/network-primitives/src/traits.rs index de6f4788796..03f5fdf2598 100644 --- a/crates/network-primitives/src/traits.rs +++ b/crates/network-primitives/src/traits.rs @@ -1,8 +1,12 @@ +use alloy_eips::eip7702::SignedAuthorization; use alloy_primitives::{Address, BlockHash, Bytes, TxHash, B256, U256}; use alloy_serde::WithOtherFields; use crate::BlockTransactions; +#[cfg(not(feature = "std"))] +use alloc::vec::Vec; + /// Receipt JSON-RPC response. pub trait ReceiptResponse { /// Address of the created contract, or `None` if the transaction was not a deployment. @@ -23,6 +27,33 @@ pub trait ReceiptResponse { /// Number of the block this transaction was included within. fn block_number(&self) -> Option; + + /// Transaction Hash. + fn transaction_hash(&self) -> TxHash; + + /// Index within the block. + fn transaction_index(&self) -> Option; + + /// Gas used by this transaction alone. + fn gas_used(&self) -> u128; + + /// Effective gas price. + fn effective_gas_price(&self) -> u128; + + /// Blob gas used by the eip-4844 transaction. + fn blob_gas_used(&self) -> Option; + + /// Blob gas price paid by the eip-4844 transaction. + fn blob_gas_price(&self) -> Option; + + /// Address of the sender. + fn from(&self) -> Address; + + /// Address of the receiver. + fn to(&self) -> Option
; + + /// EIP-7702 Authorization list. + fn authorization_list(&self) -> Option<&[SignedAuthorization]>; } /// Transaction JSON-RPC response. @@ -157,6 +188,42 @@ impl ReceiptResponse for WithOtherFields { fn block_number(&self) -> Option { self.inner.block_number() } + + fn transaction_hash(&self) -> TxHash { + self.inner.transaction_hash() + } + + fn transaction_index(&self) -> Option { + self.inner.transaction_index() + } + + fn gas_used(&self) -> u128 { + self.inner.gas_used() + } + + fn effective_gas_price(&self) -> u128 { + self.inner.effective_gas_price() + } + + fn blob_gas_used(&self) -> Option { + self.inner.blob_gas_used() + } + + fn blob_gas_price(&self) -> Option { + self.inner.blob_gas_price() + } + + fn from(&self) -> Address { + self.inner.from() + } + + fn to(&self) -> Option
{ + self.inner.to() + } + + fn authorization_list(&self) -> Option<&[SignedAuthorization]> { + self.inner.authorization_list() + } } impl BlockResponse for WithOtherFields { diff --git a/crates/rpc-types-eth/src/transaction/receipt.rs b/crates/rpc-types-eth/src/transaction/receipt.rs index f9336f09c5c..497e89e9d37 100644 --- a/crates/rpc-types-eth/src/transaction/receipt.rs +++ b/crates/rpc-types-eth/src/transaction/receipt.rs @@ -131,7 +131,7 @@ impl TransactionReceipt { pub type AnyTransactionReceipt = WithOtherFields>>; impl> ReceiptResponse for TransactionReceipt { - fn contract_address(&self) -> Option { + fn contract_address(&self) -> Option
{ self.contract_address } @@ -139,13 +139,49 @@ impl> ReceiptResponse for TransactionReceipt { self.inner.status() } - fn block_hash(&self) -> Option { + fn block_hash(&self) -> Option { self.block_hash } fn block_number(&self) -> Option { self.block_number } + + fn transaction_hash(&self) -> TxHash { + self.transaction_hash + } + + fn transaction_index(&self) -> Option { + self.transaction_index + } + + fn gas_used(&self) -> u128 { + self.gas_used + } + + fn effective_gas_price(&self) -> u128 { + self.effective_gas_price + } + + fn blob_gas_used(&self) -> Option { + self.blob_gas_used + } + + fn blob_gas_price(&self) -> Option { + self.blob_gas_price + } + + fn from(&self) -> Address { + self.from + } + + fn to(&self) -> Option
{ + self.to + } + + fn authorization_list(&self) -> Option<&[SignedAuthorization]> { + self.authorization_list.as_deref() + } } #[cfg(test)] From 35aa090318e2aee7f1256779e199be9681f3baef Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Mon, 9 Sep 2024 13:19:24 +0200 Subject: [PATCH 144/186] chore: add helpers for beacon blob bundle (#1254) --- crates/rpc-types-beacon/src/sidecar.rs | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/crates/rpc-types-beacon/src/sidecar.rs b/crates/rpc-types-beacon/src/sidecar.rs index 7ec97f9ecb3..9c2866771a2 100644 --- a/crates/rpc-types-beacon/src/sidecar.rs +++ b/crates/rpc-types-beacon/src/sidecar.rs @@ -10,7 +10,29 @@ use std::vec::IntoIter; #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct BeaconBlobBundle { /// Vec of individual blob data - data: Vec, + pub data: Vec, +} + +impl BeaconBlobBundle { + /// Creates a new [`BeaconBlobBundle`] from a given vector of [`BlobData`]. + pub const fn new(data: Vec) -> Self { + Self { data } + } + + /// Returns the number of blobs in the bundle. + pub fn len(&self) -> usize { + self.data.len() + } + + /// Returns if the bundle is empty. + pub fn is_empty(&self) -> bool { + self.data.is_empty() + } + + /// Returns the blob with the given index. + pub fn get_blob(&self, index: u64) -> Option<&BlobData> { + self.data.iter().find(|blob| blob.index == index) + } } /// Yields an iterator for BlobData From 72b5b9e7a6a82aba63c35cd85a17347239d47483 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Mon, 9 Sep 2024 13:39:30 +0200 Subject: [PATCH 145/186] chore: add aliases for Num Hash (#1253) --- crates/eips/src/eip1898.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crates/eips/src/eip1898.rs b/crates/eips/src/eip1898.rs index 16e054573bc..0a94fae57e4 100644 --- a/crates/eips/src/eip1898.rs +++ b/crates/eips/src/eip1898.rs @@ -612,6 +612,9 @@ pub struct BlockNumHash { /// Block number and hash of the forked block. pub type ForkBlock = BlockNumHash; +/// Either a hash _or_ a number +pub type NumHash = BlockNumHash; + impl BlockNumHash { /// Creates a new `BlockNumHash` from a block number and hash. pub const fn new(number: BlockNumber, hash: BlockHash) -> Self { @@ -655,6 +658,9 @@ pub enum BlockHashOrNumber { Number(u64), } +/// Either a hash _or_ a number +pub type HashOrNumber = BlockHashOrNumber; + // === impl BlockHashOrNumber === impl BlockHashOrNumber { From 4492c25f1a666881d18367dc47d0040fc05b17ae Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Mon, 9 Sep 2024 15:52:03 +0200 Subject: [PATCH 146/186] chore: release 0.3.2 --- CHANGELOG.md | 35 ++++++++++++++++++++++++++ Cargo.toml | 2 +- crates/alloy/CHANGELOG.md | 1 + crates/consensus/CHANGELOG.md | 17 +++++++++++++ crates/contract/CHANGELOG.md | 6 +++++ crates/eip7547/CHANGELOG.md | 6 +++++ crates/eips/CHANGELOG.md | 12 +++++++++ crates/genesis/CHANGELOG.md | 6 +++++ crates/json-rpc/CHANGELOG.md | 4 +++ crates/network-primitives/CHANGELOG.md | 17 +++++++++++++ crates/network/CHANGELOG.md | 6 +++++ crates/node-bindings/CHANGELOG.md | 10 ++++++++ crates/provider/CHANGELOG.md | 4 +++ crates/pubsub/CHANGELOG.md | 6 +++++ crates/rpc-client/CHANGELOG.md | 12 +++++++++ crates/rpc-types-admin/CHANGELOG.md | 6 +++++ crates/rpc-types-anvil/CHANGELOG.md | 6 +++++ crates/rpc-types-beacon/CHANGELOG.md | 12 +++++++++ crates/rpc-types-debug/CHANGELOG.md | 6 +++++ crates/rpc-types-engine/CHANGELOG.md | 12 +++++++++ crates/rpc-types-eth/CHANGELOG.md | 22 ++++++++++++++++ crates/rpc-types-mev/CHANGELOG.md | 6 +++++ crates/rpc-types-trace/CHANGELOG.md | 6 +++++ crates/rpc-types-txpool/CHANGELOG.md | 6 +++++ crates/rpc-types/CHANGELOG.md | 6 +++++ crates/serde/CHANGELOG.md | 6 +++++ crates/signer-aws/CHANGELOG.md | 6 +++++ crates/signer-gcp/CHANGELOG.md | 6 +++++ crates/signer-ledger/CHANGELOG.md | 6 +++++ crates/signer-local/CHANGELOG.md | 6 +++++ crates/signer-trezor/CHANGELOG.md | 6 +++++ crates/signer/CHANGELOG.md | 6 +++++ crates/transport-http/CHANGELOG.md | 6 +++++ crates/transport-ipc/CHANGELOG.md | 6 +++++ crates/transport-ws/CHANGELOG.md | 6 +++++ crates/transport/CHANGELOG.md | 6 +++++ 36 files changed, 297 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fb34b4ccaba..199d4e091ac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,40 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Bug Fixes + +- [consensus] Remove Unused Alloc Vecs ([#1250](https://github.com/alloy-rs/alloy/issues/1250)) + +### Dependencies + +- Bump tower to 0.5 ([#1249](https://github.com/alloy-rs/alloy/issues/1249)) + +### Features + +- No_std network primitives ([#1248](https://github.com/alloy-rs/alloy/issues/1248)) +- [rpc-types-eth] AnyBlock ([#1243](https://github.com/alloy-rs/alloy/issues/1243)) +- Add Reth node bindings ([#1092](https://github.com/alloy-rs/alloy/issues/1092)) +- [rpc-types-engine] Add forkchoice state zero helpers ([#1231](https://github.com/alloy-rs/alloy/issues/1231)) +- [network-primitives] Expose more fields via block response traits ([#1229](https://github.com/alloy-rs/alloy/issues/1229)) + +### Miscellaneous Tasks + +- Add aliases for Num Hash ([#1253](https://github.com/alloy-rs/alloy/issues/1253)) +- Add helpers for beacon blob bundle ([#1254](https://github.com/alloy-rs/alloy/issues/1254)) +- [eip1898] Display `RpcBlockHash` ([#1242](https://github.com/alloy-rs/alloy/issues/1242)) +- Optional derive more ([#1239](https://github.com/alloy-rs/alloy/issues/1239)) +- Derive more default features false ([#1230](https://github.com/alloy-rs/alloy/issues/1230)) + +### Other + +- Add getter trait methods to `ReceiptResponse` ([#1251](https://github.com/alloy-rs/alloy/issues/1251)) +- Impl `exceeds_allowed_future_timestamp` for `Header` ([#1237](https://github.com/alloy-rs/alloy/issues/1237)) +- Impl `is_zero_difficulty` for `Header` ([#1236](https://github.com/alloy-rs/alloy/issues/1236)) +- Impl parent_num_hash for Header ([#1238](https://github.com/alloy-rs/alloy/issues/1238)) +- Implement `Arbitrary` for `Header` ([#1235](https://github.com/alloy-rs/alloy/issues/1235)) + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Bug Fixes @@ -31,6 +65,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.1 - [README] Add a link to `rpc-types-debug` ([#1212](https://github.com/alloy-rs/alloy/issues/1212)) - [features] Enable `consensus` and `network` along with `providers` ([#1207](https://github.com/alloy-rs/alloy/issues/1207)) diff --git a/Cargo.toml b/Cargo.toml index ef88a7a5862..187d4282b49 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = ["crates/*"] resolver = "2" [workspace.package] -version = "0.3.1" +version = "0.3.2" edition = "2021" rust-version = "1.79" authors = ["Alloy Contributors"] diff --git a/crates/alloy/CHANGELOG.md b/crates/alloy/CHANGELOG.md index 027485de5bb..67227984de0 100644 --- a/crates/alloy/CHANGELOG.md +++ b/crates/alloy/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.1 - [features] Enable `consensus` and `network` along with `providers` ([#1207](https://github.com/alloy-rs/alloy/issues/1207)) ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 diff --git a/crates/consensus/CHANGELOG.md b/crates/consensus/CHANGELOG.md index 2efa49bcac4..eb643c51cc8 100644 --- a/crates/consensus/CHANGELOG.md +++ b/crates/consensus/CHANGELOG.md @@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Bug Fixes + +- [consensus] Remove Unused Alloc Vecs ([#1250](https://github.com/alloy-rs/alloy/issues/1250)) + +### Other + +- Impl `exceeds_allowed_future_timestamp` for `Header` ([#1237](https://github.com/alloy-rs/alloy/issues/1237)) +- Impl `is_zero_difficulty` for `Header` ([#1236](https://github.com/alloy-rs/alloy/issues/1236)) +- Impl parent_num_hash for Header ([#1238](https://github.com/alloy-rs/alloy/issues/1238)) +- Implement `Arbitrary` for `Header` ([#1235](https://github.com/alloy-rs/alloy/issues/1235)) + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Bug Fixes @@ -16,6 +29,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Derive `arbitrary::Arbitrary` for `TxEip7702` ([#1216](https://github.com/alloy-rs/alloy/issues/1216)) - Implement `tx_type` for `TxEip7702` ([#1214](https://github.com/alloy-rs/alloy/issues/1214)) +### Miscellaneous Tasks + +- Release 0.3.1 + ### Other - Rm useless methods for `TxEip7702` ([#1221](https://github.com/alloy-rs/alloy/issues/1221)) diff --git a/crates/contract/CHANGELOG.md b/crates/contract/CHANGELOG.md index a47485754f5..c726e02f08f 100644 --- a/crates/contract/CHANGELOG.md +++ b/crates/contract/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Bug Fixes diff --git a/crates/eip7547/CHANGELOG.md b/crates/eip7547/CHANGELOG.md index 1c20d59a82e..2fa94e9f648 100644 --- a/crates/eip7547/CHANGELOG.md +++ b/crates/eip7547/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Miscellaneous Tasks diff --git a/crates/eips/CHANGELOG.md b/crates/eips/CHANGELOG.md index a1bd97c3a68..97ed2aa817d 100644 --- a/crates/eips/CHANGELOG.md +++ b/crates/eips/CHANGELOG.md @@ -5,12 +5,24 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Miscellaneous Tasks + +- Add aliases for Num Hash ([#1253](https://github.com/alloy-rs/alloy/issues/1253)) +- [eip1898] Display `RpcBlockHash` ([#1242](https://github.com/alloy-rs/alloy/issues/1242)) +- Optional derive more ([#1239](https://github.com/alloy-rs/alloy/issues/1239)) + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Bug Fixes - [eips] No-std compat ([#1222](https://github.com/alloy-rs/alloy/issues/1222)) +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Bug Fixes diff --git a/crates/genesis/CHANGELOG.md b/crates/genesis/CHANGELOG.md index a25f1dcdf92..50c3d6c338c 100644 --- a/crates/genesis/CHANGELOG.md +++ b/crates/genesis/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Features diff --git a/crates/json-rpc/CHANGELOG.md b/crates/json-rpc/CHANGELOG.md index b9f9cedffae..58c14390057 100644 --- a/crates/json-rpc/CHANGELOG.md +++ b/crates/json-rpc/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [`json-rpc`] Implement From U256 and String for SubId ([#1226](https://github.com/alloy-rs/alloy/issues/1226)) +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Bug Fixes diff --git a/crates/network-primitives/CHANGELOG.md b/crates/network-primitives/CHANGELOG.md index a2be30b8738..34493e0b59f 100644 --- a/crates/network-primitives/CHANGELOG.md +++ b/crates/network-primitives/CHANGELOG.md @@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Features + +- No_std network primitives ([#1248](https://github.com/alloy-rs/alloy/issues/1248)) +- [network-primitives] Expose more fields via block response traits ([#1229](https://github.com/alloy-rs/alloy/issues/1229)) + +### Other + +- Add getter trait methods to `ReceiptResponse` ([#1251](https://github.com/alloy-rs/alloy/issues/1251)) + +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Bug Fixes diff --git a/crates/network/CHANGELOG.md b/crates/network/CHANGELOG.md index ac4b8b90666..702734d4a26 100644 --- a/crates/network/CHANGELOG.md +++ b/crates/network/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Bug Fixes diff --git a/crates/node-bindings/CHANGELOG.md b/crates/node-bindings/CHANGELOG.md index 3a10b988515..a8f3cf9b8a8 100644 --- a/crates/node-bindings/CHANGELOG.md +++ b/crates/node-bindings/CHANGELOG.md @@ -5,12 +5,22 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Features + +- Add Reth node bindings ([#1092](https://github.com/alloy-rs/alloy/issues/1092)) + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Bug Fixes - Anvil builder default port ([#1213](https://github.com/alloy-rs/alloy/issues/1213)) +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Bug Fixes diff --git a/crates/provider/CHANGELOG.md b/crates/provider/CHANGELOG.md index 139e758badd..f6b2d5d88db 100644 --- a/crates/provider/CHANGELOG.md +++ b/crates/provider/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [alloy-provider] Add abstraction for `NonceFiller` behavior ([#1108](https://github.com/alloy-rs/alloy/issues/1108)) +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Bug Fixes diff --git a/crates/pubsub/CHANGELOG.md b/crates/pubsub/CHANGELOG.md index 171b5b2965c..72e4b818fe6 100644 --- a/crates/pubsub/CHANGELOG.md +++ b/crates/pubsub/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Bug Fixes diff --git a/crates/rpc-client/CHANGELOG.md b/crates/rpc-client/CHANGELOG.md index 53de2a84f6b..da0bfa222af 100644 --- a/crates/rpc-client/CHANGELOG.md +++ b/crates/rpc-client/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Dependencies + +- Bump tower to 0.5 ([#1249](https://github.com/alloy-rs/alloy/issues/1249)) + +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Bug Fixes diff --git a/crates/rpc-types-admin/CHANGELOG.md b/crates/rpc-types-admin/CHANGELOG.md index c562d3318af..4e4faf9aa82 100644 --- a/crates/rpc-types-admin/CHANGELOG.md +++ b/crates/rpc-types-admin/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Bug Fixes diff --git a/crates/rpc-types-anvil/CHANGELOG.md b/crates/rpc-types-anvil/CHANGELOG.md index 109428c82ce..e233404cfac 100644 --- a/crates/rpc-types-anvil/CHANGELOG.md +++ b/crates/rpc-types-anvil/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Miscellaneous Tasks diff --git a/crates/rpc-types-beacon/CHANGELOG.md b/crates/rpc-types-beacon/CHANGELOG.md index 81dbc4c816a..5aa55bb9cac 100644 --- a/crates/rpc-types-beacon/CHANGELOG.md +++ b/crates/rpc-types-beacon/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Miscellaneous Tasks + +- Add helpers for beacon blob bundle ([#1254](https://github.com/alloy-rs/alloy/issues/1254)) + +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Bug Fixes diff --git a/crates/rpc-types-debug/CHANGELOG.md b/crates/rpc-types-debug/CHANGELOG.md index 69372189c6f..826872ddb63 100644 --- a/crates/rpc-types-debug/CHANGELOG.md +++ b/crates/rpc-types-debug/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Features diff --git a/crates/rpc-types-engine/CHANGELOG.md b/crates/rpc-types-engine/CHANGELOG.md index a02ac157920..cb79cec60ce 100644 --- a/crates/rpc-types-engine/CHANGELOG.md +++ b/crates/rpc-types-engine/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Features + +- [rpc-types-engine] Add forkchoice state zero helpers ([#1231](https://github.com/alloy-rs/alloy/issues/1231)) + +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Bug Fixes diff --git a/crates/rpc-types-eth/CHANGELOG.md b/crates/rpc-types-eth/CHANGELOG.md index f6cb2578afc..829e58d9b88 100644 --- a/crates/rpc-types-eth/CHANGELOG.md +++ b/crates/rpc-types-eth/CHANGELOG.md @@ -5,6 +5,28 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Bug Fixes + +- [consensus] Remove Unused Alloc Vecs ([#1250](https://github.com/alloy-rs/alloy/issues/1250)) + +### Features + +- No_std network primitives ([#1248](https://github.com/alloy-rs/alloy/issues/1248)) +- [rpc-types-eth] AnyBlock ([#1243](https://github.com/alloy-rs/alloy/issues/1243)) +- [network-primitives] Expose more fields via block response traits ([#1229](https://github.com/alloy-rs/alloy/issues/1229)) + +### Other + +- Add getter trait methods to `ReceiptResponse` ([#1251](https://github.com/alloy-rs/alloy/issues/1251)) + +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Bug Fixes diff --git a/crates/rpc-types-mev/CHANGELOG.md b/crates/rpc-types-mev/CHANGELOG.md index d2989edff30..e2ab6c42dfb 100644 --- a/crates/rpc-types-mev/CHANGELOG.md +++ b/crates/rpc-types-mev/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Miscellaneous Tasks diff --git a/crates/rpc-types-trace/CHANGELOG.md b/crates/rpc-types-trace/CHANGELOG.md index a76bb7a0944..bff8435c76a 100644 --- a/crates/rpc-types-trace/CHANGELOG.md +++ b/crates/rpc-types-trace/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Bug Fixes diff --git a/crates/rpc-types-txpool/CHANGELOG.md b/crates/rpc-types-txpool/CHANGELOG.md index 659a3fcd676..5ccb69008e5 100644 --- a/crates/rpc-types-txpool/CHANGELOG.md +++ b/crates/rpc-types-txpool/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Features diff --git a/crates/rpc-types/CHANGELOG.md b/crates/rpc-types/CHANGELOG.md index 8e8008ac46a..6d02ddb0e54 100644 --- a/crates/rpc-types/CHANGELOG.md +++ b/crates/rpc-types/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Dependencies diff --git a/crates/serde/CHANGELOG.md b/crates/serde/CHANGELOG.md index 1bfadc52d40..da2025dea45 100644 --- a/crates/serde/CHANGELOG.md +++ b/crates/serde/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Miscellaneous Tasks diff --git a/crates/signer-aws/CHANGELOG.md b/crates/signer-aws/CHANGELOG.md index d4bb9f32e1e..3d44aeda1e5 100644 --- a/crates/signer-aws/CHANGELOG.md +++ b/crates/signer-aws/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Miscellaneous Tasks diff --git a/crates/signer-gcp/CHANGELOG.md b/crates/signer-gcp/CHANGELOG.md index ea4c97e1900..ee852b83c1b 100644 --- a/crates/signer-gcp/CHANGELOG.md +++ b/crates/signer-gcp/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Dependencies diff --git a/crates/signer-ledger/CHANGELOG.md b/crates/signer-ledger/CHANGELOG.md index b02d7671342..dcdd290a995 100644 --- a/crates/signer-ledger/CHANGELOG.md +++ b/crates/signer-ledger/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Dependencies diff --git a/crates/signer-local/CHANGELOG.md b/crates/signer-local/CHANGELOG.md index 82908cd00df..0d12e814519 100644 --- a/crates/signer-local/CHANGELOG.md +++ b/crates/signer-local/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Dependencies diff --git a/crates/signer-trezor/CHANGELOG.md b/crates/signer-trezor/CHANGELOG.md index f3629b8e143..68e91178338 100644 --- a/crates/signer-trezor/CHANGELOG.md +++ b/crates/signer-trezor/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Dependencies diff --git a/crates/signer/CHANGELOG.md b/crates/signer/CHANGELOG.md index efca8a2e14d..bbe1a19359f 100644 --- a/crates/signer/CHANGELOG.md +++ b/crates/signer/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Features diff --git a/crates/transport-http/CHANGELOG.md b/crates/transport-http/CHANGELOG.md index a2b88a9d0af..1b69a3ffac1 100644 --- a/crates/transport-http/CHANGELOG.md +++ b/crates/transport-http/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Miscellaneous Tasks diff --git a/crates/transport-ipc/CHANGELOG.md b/crates/transport-ipc/CHANGELOG.md index 90545888075..e646f8a0229 100644 --- a/crates/transport-ipc/CHANGELOG.md +++ b/crates/transport-ipc/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Miscellaneous Tasks diff --git a/crates/transport-ws/CHANGELOG.md b/crates/transport-ws/CHANGELOG.md index 036104ab7d5..24f4f510f0c 100644 --- a/crates/transport-ws/CHANGELOG.md +++ b/crates/transport-ws/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Miscellaneous Tasks diff --git a/crates/transport/CHANGELOG.md b/crates/transport/CHANGELOG.md index 61ecee9f62e..d448e84917f 100644 --- a/crates/transport/CHANGELOG.md +++ b/crates/transport/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 + +### Miscellaneous Tasks + +- Release 0.3.1 + ## [0.3.0](https://github.com/alloy-rs/alloy/releases/tag/v0.3.0) - 2024-08-28 ### Documentation From 7b487e444d1d4e8799c06c5d705732160d5ca015 Mon Sep 17 00:00:00 2001 From: Delweng Date: Tue, 10 Sep 2024 00:41:04 +0800 Subject: [PATCH 147/186] feat(rpc-types-trace): always serialize result if no error (#1258) * feat(rpc-types-trace): error or result Signed-off-by: jsvisa * add a test case Signed-off-by: jsvisa * feat: error + result Signed-off-by: jsvisa * touchup --------- Signed-off-by: jsvisa Co-authored-by: Matthias Seitz --- crates/rpc-types-trace/src/parity.rs | 53 +++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/crates/rpc-types-trace/src/parity.rs b/crates/rpc-types-trace/src/parity.rs index b6794694eb7..a740bd14780 100644 --- a/crates/rpc-types-trace/src/parity.rs +++ b/crates/rpc-types-trace/src/parity.rs @@ -429,6 +429,7 @@ pub struct TransactionTrace { #[serde(skip_serializing_if = "Option::is_none")] pub error: Option, /// Output of the trace, can be CALL or CREATE + #[serde(default)] pub result: Option, /// How many subtraces this trace has. pub subtraces: usize, @@ -498,15 +499,10 @@ impl Serialize for LocalizedTransactionTrace { if let Some(error) = error { s.serialize_field("error", error)?; } - match result { - Some(TraceOutput::Call(call)) => { - s.serialize_field("result", call)?; - } - Some(TraceOutput::Create(create)) => { - s.serialize_field("result", create)?; - } - None => {} + Some(TraceOutput::Call(call)) => s.serialize_field("result", call)?, + Some(TraceOutput::Create(create)) => s.serialize_field("result", create)?, + None => s.serialize_field("result", &None::<()>)?, } s.serialize_field("subtraces", &subtraces)?; @@ -822,6 +818,47 @@ mod tests { let serialized = serde_json::to_string_pretty(&trace).unwrap(); similar_asserts::assert_eq!(serialized, reference_data); } + + #[test] + fn test_transaction_trace_null_result() { + let trace = TransactionTrace { + action: Action::Call(CallAction { + from: Address::from_str("0x1234567890123456789012345678901234567890").unwrap(), + call_type: CallType::Call, + gas: 100000, + input: Bytes::from_str("0x1234").unwrap(), + to: Address::from_str("0x0987654321098765432109876543210987654321").unwrap(), + value: U256::from(0), + }), + ..Default::default() + }; + + let serialized = serde_json::to_string(&trace).unwrap(); + let deserialized: serde_json::Value = serde_json::from_str(&serialized).unwrap(); + + assert_eq!(deserialized["result"], serde_json::Value::Null); + assert!(deserialized.as_object().unwrap().contains_key("result")); + assert!(!deserialized.as_object().unwrap().contains_key("error")); + + let deserialized_trace: TransactionTrace = serde_json::from_str(&serialized).unwrap(); + assert_eq!(deserialized_trace.result, None); + } + + #[test] + fn test_transaction_trace_error_result() { + let trace = TransactionTrace { error: Some("Reverted".to_string()), ..Default::default() }; + + let serialized = serde_json::to_string(&trace).unwrap(); + let deserialized: serde_json::Value = serde_json::from_str(&serialized).unwrap(); + + assert_eq!(deserialized["result"], serde_json::Value::Null); + assert!(deserialized.as_object().unwrap().contains_key("result")); + assert!(deserialized.as_object().unwrap().contains_key("error")); + + let deserialized_trace: TransactionTrace = serde_json::from_str(&serialized).unwrap(); + assert_eq!(deserialized_trace.result, None); + } + #[test] fn test_nethermind_trace_result_null_output_value() { let reference_data = r#"{ From 9c8bcccc50167750a5955bf312a1d7db4eabd284 Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Mon, 9 Sep 2024 10:00:08 -0700 Subject: [PATCH 148/186] consensus: implement `AsRef` for `Header` (#1260) consensus: implement AsRef for Header --- crates/consensus/src/header.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crates/consensus/src/header.rs b/crates/consensus/src/header.rs index ae7bed24ae1..3c086b8b045 100644 --- a/crates/consensus/src/header.rs +++ b/crates/consensus/src/header.rs @@ -135,6 +135,12 @@ pub struct Header { pub extra_data: Bytes, } +impl AsRef for Header { + fn as_ref(&self) -> &Self { + self + } +} + impl Default for Header { fn default() -> Self { Self { From 1e9f45a8fc9062b632a60a48dea249287c5badb2 Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Tue, 10 Sep 2024 02:42:42 +0530 Subject: [PATCH 149/186] fix(rpc-types-trace): use rpc-types Log in OtsReceipt (#1261) --- crates/rpc-types-trace/src/otterscan.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/rpc-types-trace/src/otterscan.rs b/crates/rpc-types-trace/src/otterscan.rs index 8c93ca9c9d9..903edf5a594 100644 --- a/crates/rpc-types-trace/src/otterscan.rs +++ b/crates/rpc-types-trace/src/otterscan.rs @@ -4,7 +4,7 @@ //! use alloy_primitives::{Address, Bloom, Bytes, TxHash, B256, U256}; -use alloy_rpc_types_eth::{Block, Header, Transaction, TransactionReceipt, Withdrawal}; +use alloy_rpc_types_eth::{Block, Header, Log, Transaction, TransactionReceipt, Withdrawal}; use serde::{ de::{self, Unexpected}, Deserialize, Deserializer, Serialize, Serializer, @@ -204,7 +204,7 @@ pub struct OtsReceipt { /// The logs sent from contracts. /// /// Note: this is set to null. - pub logs: Option>, + pub logs: Option>, /// The bloom filter. /// /// Note: this is set to null. From a8e5ae27dce6b97842d3d63411c66768dc3112b2 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 10 Sep 2024 01:57:35 +0200 Subject: [PATCH 150/186] test: dont use fork test (#1263) --- crates/node-bindings/src/nodes/anvil.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/node-bindings/src/nodes/anvil.rs b/crates/node-bindings/src/nodes/anvil.rs index 0572cf0fdd1..7fbdf1f4c30 100644 --- a/crates/node-bindings/src/nodes/anvil.rs +++ b/crates/node-bindings/src/nodes/anvil.rs @@ -408,8 +408,9 @@ mod tests { #[test] fn assert_chain_id() { - let anvil = Anvil::new().fork("https://eth.llamarpc.com ").spawn(); - assert_eq!(anvil.chain_id(), 1); + let id = 99999; + let anvil = Anvil::new().chain_id(id).spawn(); + assert_eq!(anvil.chain_id(), id); } #[test] From 06dccfe778995f9ab55436955ff9cf750021ae51 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 10 Sep 2024 02:50:17 +0200 Subject: [PATCH 151/186] chore: swap BlockNumHash alias and struct name (#1265) * chore: swap BlockNumHash alias and struct name * clippy --- crates/eips/src/eip1898.rs | 38 +++++++++++++++++++------------------- crates/eips/src/lib.rs | 2 +- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/crates/eips/src/eip1898.rs b/crates/eips/src/eip1898.rs index 0a94fae57e4..8a298d5a7e6 100644 --- a/crates/eips/src/eip1898.rs +++ b/crates/eips/src/eip1898.rs @@ -1,6 +1,6 @@ //! [EIP-1898]: https://eips.ethereum.org/EIPS/eip-1898 -use alloy_primitives::{hex::FromHexError, ruint::ParseError, BlockHash, BlockNumber, B256, U64}; +use alloy_primitives::{hex::FromHexError, ruint::ParseError, BlockHash, B256, U64}; use alloy_rlp::{bytes, Decodable, Encodable, Error as RlpError}; use core::{ fmt::{self, Debug, Display, Formatter}, @@ -600,29 +600,29 @@ impl FromStr for BlockId { } } -/// Block number and hash. +/// A number and a hash. #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)] -pub struct BlockNumHash { - /// Block number - pub number: BlockNumber, - /// Block hash - pub hash: BlockHash, +pub struct NumHash { + /// The number + pub number: u64, + /// The hash. + pub hash: B256, } /// Block number and hash of the forked block. -pub type ForkBlock = BlockNumHash; +pub type ForkBlock = NumHash; -/// Either a hash _or_ a number -pub type NumHash = BlockNumHash; +/// A block number and a hash +pub type BlockNumHash = NumHash; -impl BlockNumHash { - /// Creates a new `BlockNumHash` from a block number and hash. - pub const fn new(number: BlockNumber, hash: BlockHash) -> Self { +impl NumHash { + /// Creates a new `NumHash` from a number and hash. + pub const fn new(number: u64, hash: B256) -> Self { Self { number, hash } } - /// Consumes `Self` and returns [`BlockNumber`], [`BlockHash`] - pub const fn into_components(self) -> (BlockNumber, BlockHash) { + /// Consumes `Self` and returns the number and hash + pub const fn into_components(self) -> (u64, B256) { (self.number, self.hash) } @@ -635,14 +635,14 @@ impl BlockNumHash { } } -impl From<(BlockNumber, BlockHash)> for BlockNumHash { - fn from(val: (BlockNumber, BlockHash)) -> Self { +impl From<(u64, B256)> for NumHash { + fn from(val: (u64, B256)) -> Self { Self { number: val.0, hash: val.1 } } } -impl From<(BlockHash, BlockNumber)> for BlockNumHash { - fn from(val: (BlockHash, BlockNumber)) -> Self { +impl From<(B256, u64)> for NumHash { + fn from(val: (B256, u64)) -> Self { Self { hash: val.0, number: val.1 } } } diff --git a/crates/eips/src/lib.rs b/crates/eips/src/lib.rs index 393ba4f343e..774067e694a 100644 --- a/crates/eips/src/lib.rs +++ b/crates/eips/src/lib.rs @@ -16,7 +16,7 @@ pub use eip1559::calc_next_block_base_fee; pub mod eip1898; pub use eip1898::{ - BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag, ForkBlock, RpcBlockHash, + BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag, ForkBlock, NumHash, RpcBlockHash, }; pub mod eip2718; From c9980cc36e06afa3abebc6806e9417d1f1d3e805 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 10 Sep 2024 02:54:00 +0200 Subject: [PATCH 152/186] chore: require destination for 7702 (#1262) * chore: require destination for 7702 * Update crates/consensus/src/transaction/eip7702.rs Co-authored-by: DaniPopes <57450786+DaniPopes@users.noreply.github.com> * review * clippy --------- Co-authored-by: DaniPopes <57450786+DaniPopes@users.noreply.github.com> --- crates/consensus/src/header.rs | 3 +-- crates/consensus/src/transaction/eip7702.rs | 20 +++++++++---------- crates/consensus/src/transaction/envelope.rs | 4 ++-- crates/rpc-types-eth/src/transaction/mod.rs | 2 +- .../rpc-types-eth/src/transaction/request.rs | 6 +++--- 5 files changed, 16 insertions(+), 19 deletions(-) diff --git a/crates/consensus/src/header.rs b/crates/consensus/src/header.rs index 3c086b8b045..55045b03dc0 100644 --- a/crates/consensus/src/header.rs +++ b/crates/consensus/src/header.rs @@ -639,11 +639,10 @@ impl<'a> arbitrary::Arbitrary<'a> for Header { } } -#[cfg(test)] +#[cfg(all(test, feature = "serde"))] mod tests { use super::*; - #[cfg(feature = "serde")] #[test] fn header_serde() { let raw = r#"{"parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000","ommersHash":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","beneficiary":"0x0000000000000000000000000000000000000000","stateRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","withdrawalsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","difficulty":"0x0","number":"0x0","gasLimit":"0x0","gasUsed":"0x0","timestamp":"0x0","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0000000000000000","baseFeePerGas":"0x1","extraData":"0x"}"#; diff --git a/crates/consensus/src/transaction/eip7702.rs b/crates/consensus/src/transaction/eip7702.rs index c2e704a4df8..a0dc1fde7e1 100644 --- a/crates/consensus/src/transaction/eip7702.rs +++ b/crates/consensus/src/transaction/eip7702.rs @@ -1,6 +1,6 @@ use crate::{EncodableSignature, SignableTransaction, Signed, Transaction, TxType}; use alloy_eips::eip2930::AccessList; -use alloy_primitives::{keccak256, Bytes, ChainId, Signature, TxKind, B256, U256}; +use alloy_primitives::{keccak256, Address, Bytes, ChainId, Signature, TxKind, B256, U256}; use alloy_rlp::{BufMut, Decodable, Encodable, Header}; use core::mem; @@ -50,10 +50,8 @@ pub struct TxEip7702 { /// This is also known as `GasTipCap` #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))] pub max_priority_fee_per_gas: u128, - /// The 160-bit address of the message call’s recipient or, for a contract creation - /// transaction, ∅, used here to denote the only member of B0 ; formally Tt. - #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "TxKind::is_create"))] - pub to: TxKind, + /// The 160-bit address of the message call’s recipient. + pub to: Address, /// A scalar value equal to the number of Wei to /// be transferred to the message call’s recipient or, /// in the case of contract creation, as an endowment @@ -263,7 +261,7 @@ impl TxEip7702 { mem::size_of::() + // gas_limit mem::size_of::() + // max_fee_per_gas mem::size_of::() + // max_priority_fee_per_gas - self.to.size() + // to + mem::size_of::
() + // to mem::size_of::() + // value self.access_list.size() + // access_list self.input.len() + // input @@ -305,7 +303,7 @@ impl Transaction for TxEip7702 { } fn to(&self) -> TxKind { - self.to + self.to.into() } fn value(&self) -> U256 { @@ -391,7 +389,7 @@ mod tests { use super::TxEip7702; use crate::SignableTransaction; use alloy_eips::eip2930::AccessList; - use alloy_primitives::{address, b256, hex, Address, Signature, TxKind, U256}; + use alloy_primitives::{address, b256, hex, Address, Signature, U256}; #[test] fn encode_decode_eip7702() { @@ -399,7 +397,7 @@ mod tests { chain_id: 1, nonce: 0x42, gas_limit: 44386, - to: address!("6069a6c32cf691f5982febae4faf8a6f3ab2f0f6").into(), + to: address!("6069a6c32cf691f5982febae4faf8a6f3ab2f0f6"), value: U256::from(0_u64), input: hex!("a22cb4650000000000000000000000005eee75727d804a2b13038928d36f8b188945a57a0000000000000000000000000000000000000000000000000000000000000000").into(), max_fee_per_gas: 0x4a817c800, @@ -430,7 +428,7 @@ mod tests { max_fee_per_gas: 0x4a817c800, max_priority_fee_per_gas: 0x3b9aca00, gas_limit: 2, - to: TxKind::Create, + to: Address::default(), value: U256::ZERO, input: vec![1, 2].into(), access_list: Default::default(), @@ -456,7 +454,7 @@ mod tests { max_fee_per_gas: 0x4a817c800, max_priority_fee_per_gas: 0x3b9aca00, gas_limit: 2, - to: Address::default().into(), + to: Address::default(), value: U256::ZERO, input: vec![1, 2].into(), access_list: Default::default(), diff --git a/crates/consensus/src/transaction/envelope.rs b/crates/consensus/src/transaction/envelope.rs index fc5c324e983..232e88ca326 100644 --- a/crates/consensus/src/transaction/envelope.rs +++ b/crates/consensus/src/transaction/envelope.rs @@ -823,7 +823,7 @@ mod tests { gas_limit: 3, max_fee_per_gas: 4, max_priority_fee_per_gas: 5, - to: Address::left_padding_from(&[5]).into(), + to: Address::left_padding_from(&[5]), value: U256::from(6_u64), input: vec![7].into(), access_list: AccessList(vec![AccessListItem { @@ -994,7 +994,7 @@ mod tests { gas_limit: u128::MAX, max_fee_per_gas: u128::MAX, max_priority_fee_per_gas: u128::MAX, - to: Address::random().into(), + to: Address::random(), value: U256::MAX, input: Bytes::new(), access_list: AccessList(vec![AccessListItem { diff --git a/crates/rpc-types-eth/src/transaction/mod.rs b/crates/rpc-types-eth/src/transaction/mod.rs index 6d6262cdd0f..1700bcf33bd 100644 --- a/crates/rpc-types-eth/src/transaction/mod.rs +++ b/crates/rpc-types-eth/src/transaction/mod.rs @@ -269,7 +269,7 @@ impl TryFrom for Signed { max_priority_fee_per_gas: tx .max_priority_fee_per_gas .ok_or(ConversionError::MissingMaxPriorityFeePerGas)?, - to: tx.to.into(), + to: tx.to.ok_or(ConversionError::MissingTo)?, value: tx.value, access_list: tx.access_list.ok_or(ConversionError::MissingAccessList)?, authorization_list: tx diff --git a/crates/rpc-types-eth/src/transaction/request.rs b/crates/rpc-types-eth/src/transaction/request.rs index aacd3f3af70..0a037d300d2 100644 --- a/crates/rpc-types-eth/src/transaction/request.rs +++ b/crates/rpc-types-eth/src/transaction/request.rs @@ -312,7 +312,7 @@ impl TransactionRequest { /// If required fields are missing. Use `complete_7702` to check if the /// request can be built. fn build_7702(self) -> Result { - let checked_to = self.to.ok_or("Missing 'to' field for Eip7702 transaction.")?; + let to_address = self.to.ok_or("Missing 'to' field for Eip7702 transaction.")?.to().copied().ok_or("The field `to` can only be of type TxKind::Call(Account). Please change it accordingly.")?; Ok(TxEip7702 { chain_id: self.chain_id.unwrap_or(1), @@ -324,7 +324,7 @@ impl TransactionRequest { max_priority_fee_per_gas: self .max_priority_fee_per_gas .ok_or("Missing 'max_priority_fee_per_gas' field for Eip7702 transaction.")?, - to: checked_to, + to: to_address, value: self.value.unwrap_or_default(), input: self.input.into_input().unwrap_or_default(), access_list: self.access_list.unwrap_or_default(), @@ -808,7 +808,7 @@ impl From for TransactionRequest { impl From for TransactionRequest { fn from(tx: TxEip7702) -> Self { Self { - to: if let TxKind::Call(to) = tx.to { Some(to.into()) } else { None }, + to: Some(tx.to.into()), gas: Some(tx.gas_limit), max_fee_per_gas: Some(tx.max_fee_per_gas), max_priority_fee_per_gas: Some(tx.max_priority_fee_per_gas), From c558a5cfc5feedf351fff37019bf14c02964bf52 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 10 Sep 2024 12:51:46 +0200 Subject: [PATCH 153/186] chore: release 0.3.3 --- CHANGELOG.md | 24 ++++++++++++++++++++++++ Cargo.toml | 2 +- crates/alloy/CHANGELOG.md | 6 ++++++ crates/consensus/CHANGELOG.md | 14 ++++++++++++++ crates/contract/CHANGELOG.md | 6 ++++++ crates/eip7547/CHANGELOG.md | 6 ++++++ crates/eips/CHANGELOG.md | 7 +++++++ crates/genesis/CHANGELOG.md | 6 ++++++ crates/json-rpc/CHANGELOG.md | 6 ++++++ crates/network-primitives/CHANGELOG.md | 4 ++++ crates/network/CHANGELOG.md | 6 ++++++ crates/node-bindings/CHANGELOG.md | 10 ++++++++++ crates/provider/CHANGELOG.md | 6 ++++++ crates/pubsub/CHANGELOG.md | 6 ++++++ crates/rpc-client/CHANGELOG.md | 4 ++++ crates/rpc-types-admin/CHANGELOG.md | 6 ++++++ crates/rpc-types-anvil/CHANGELOG.md | 6 ++++++ crates/rpc-types-beacon/CHANGELOG.md | 1 + crates/rpc-types-debug/CHANGELOG.md | 6 ++++++ crates/rpc-types-engine/CHANGELOG.md | 4 ++++ crates/rpc-types-eth/CHANGELOG.md | 10 ++++++++++ crates/rpc-types-mev/CHANGELOG.md | 6 ++++++ crates/rpc-types-trace/CHANGELOG.md | 16 ++++++++++++++++ crates/rpc-types-txpool/CHANGELOG.md | 6 ++++++ crates/rpc-types/CHANGELOG.md | 6 ++++++ crates/serde/CHANGELOG.md | 6 ++++++ crates/signer-aws/CHANGELOG.md | 6 ++++++ crates/signer-gcp/CHANGELOG.md | 6 ++++++ crates/signer-ledger/CHANGELOG.md | 6 ++++++ crates/signer-local/CHANGELOG.md | 6 ++++++ crates/signer-trezor/CHANGELOG.md | 6 ++++++ crates/signer/CHANGELOG.md | 6 ++++++ crates/transport-http/CHANGELOG.md | 6 ++++++ crates/transport-ipc/CHANGELOG.md | 6 ++++++ crates/transport-ws/CHANGELOG.md | 6 ++++++ crates/transport/CHANGELOG.md | 6 ++++++ 36 files changed, 245 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 199d4e091ac..fe15ae36cfa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,29 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Bug Fixes + +- [rpc-types-trace] Use rpc-types Log in OtsReceipt ([#1261](https://github.com/alloy-rs/alloy/issues/1261)) + +### Features + +- [rpc-types-trace] Always serialize result if no error ([#1258](https://github.com/alloy-rs/alloy/issues/1258)) + +### Miscellaneous Tasks + +- Require destination for 7702 ([#1262](https://github.com/alloy-rs/alloy/issues/1262)) +- Swap BlockNumHash alias and struct name ([#1265](https://github.com/alloy-rs/alloy/issues/1265)) + +### Other + +- Implement `AsRef` for `Header` ([#1260](https://github.com/alloy-rs/alloy/issues/1260)) + +### Testing + +- Dont use fork test ([#1263](https://github.com/alloy-rs/alloy/issues/1263)) + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Bug Fixes @@ -25,6 +48,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.2 - Add aliases for Num Hash ([#1253](https://github.com/alloy-rs/alloy/issues/1253)) - Add helpers for beacon blob bundle ([#1254](https://github.com/alloy-rs/alloy/issues/1254)) - [eip1898] Display `RpcBlockHash` ([#1242](https://github.com/alloy-rs/alloy/issues/1242)) diff --git a/Cargo.toml b/Cargo.toml index 187d4282b49..9ce5c6f391a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = ["crates/*"] resolver = "2" [workspace.package] -version = "0.3.2" +version = "0.3.3" edition = "2021" rust-version = "1.79" authors = ["Alloy Contributors"] diff --git a/crates/alloy/CHANGELOG.md b/crates/alloy/CHANGELOG.md index 67227984de0..8ca92dfdd18 100644 --- a/crates/alloy/CHANGELOG.md +++ b/crates/alloy/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Miscellaneous Tasks diff --git a/crates/consensus/CHANGELOG.md b/crates/consensus/CHANGELOG.md index eb643c51cc8..44727c60c6a 100644 --- a/crates/consensus/CHANGELOG.md +++ b/crates/consensus/CHANGELOG.md @@ -5,12 +5,26 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Require destination for 7702 ([#1262](https://github.com/alloy-rs/alloy/issues/1262)) + +### Other + +- Implement `AsRef` for `Header` ([#1260](https://github.com/alloy-rs/alloy/issues/1260)) + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Bug Fixes - [consensus] Remove Unused Alloc Vecs ([#1250](https://github.com/alloy-rs/alloy/issues/1250)) +### Miscellaneous Tasks + +- Release 0.3.2 + ### Other - Impl `exceeds_allowed_future_timestamp` for `Header` ([#1237](https://github.com/alloy-rs/alloy/issues/1237)) diff --git a/crates/contract/CHANGELOG.md b/crates/contract/CHANGELOG.md index c726e02f08f..870071431f2 100644 --- a/crates/contract/CHANGELOG.md +++ b/crates/contract/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Miscellaneous Tasks diff --git a/crates/eip7547/CHANGELOG.md b/crates/eip7547/CHANGELOG.md index 2fa94e9f648..ccfb3e6e671 100644 --- a/crates/eip7547/CHANGELOG.md +++ b/crates/eip7547/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Miscellaneous Tasks diff --git a/crates/eips/CHANGELOG.md b/crates/eips/CHANGELOG.md index 97ed2aa817d..87273665698 100644 --- a/crates/eips/CHANGELOG.md +++ b/crates/eips/CHANGELOG.md @@ -5,10 +5,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Swap BlockNumHash alias and struct name ([#1265](https://github.com/alloy-rs/alloy/issues/1265)) + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Miscellaneous Tasks +- Release 0.3.2 - Add aliases for Num Hash ([#1253](https://github.com/alloy-rs/alloy/issues/1253)) - [eip1898] Display `RpcBlockHash` ([#1242](https://github.com/alloy-rs/alloy/issues/1242)) - Optional derive more ([#1239](https://github.com/alloy-rs/alloy/issues/1239)) diff --git a/crates/genesis/CHANGELOG.md b/crates/genesis/CHANGELOG.md index 50c3d6c338c..0edc493fc42 100644 --- a/crates/genesis/CHANGELOG.md +++ b/crates/genesis/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Miscellaneous Tasks diff --git a/crates/json-rpc/CHANGELOG.md b/crates/json-rpc/CHANGELOG.md index 58c14390057..68c637a1e41 100644 --- a/crates/json-rpc/CHANGELOG.md +++ b/crates/json-rpc/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Features diff --git a/crates/network-primitives/CHANGELOG.md b/crates/network-primitives/CHANGELOG.md index 34493e0b59f..3137d71f4c0 100644 --- a/crates/network-primitives/CHANGELOG.md +++ b/crates/network-primitives/CHANGELOG.md @@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - No_std network primitives ([#1248](https://github.com/alloy-rs/alloy/issues/1248)) - [network-primitives] Expose more fields via block response traits ([#1229](https://github.com/alloy-rs/alloy/issues/1229)) +### Miscellaneous Tasks + +- Release 0.3.2 + ### Other - Add getter trait methods to `ReceiptResponse` ([#1251](https://github.com/alloy-rs/alloy/issues/1251)) diff --git a/crates/network/CHANGELOG.md b/crates/network/CHANGELOG.md index 702734d4a26..1ef0332c8cc 100644 --- a/crates/network/CHANGELOG.md +++ b/crates/network/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Miscellaneous Tasks diff --git a/crates/node-bindings/CHANGELOG.md b/crates/node-bindings/CHANGELOG.md index a8f3cf9b8a8..656c9ad6af0 100644 --- a/crates/node-bindings/CHANGELOG.md +++ b/crates/node-bindings/CHANGELOG.md @@ -5,12 +5,22 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Testing + +- Dont use fork test ([#1263](https://github.com/alloy-rs/alloy/issues/1263)) + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Features - Add Reth node bindings ([#1092](https://github.com/alloy-rs/alloy/issues/1092)) +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Bug Fixes diff --git a/crates/provider/CHANGELOG.md b/crates/provider/CHANGELOG.md index f6b2d5d88db..ec09db707ae 100644 --- a/crates/provider/CHANGELOG.md +++ b/crates/provider/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Features diff --git a/crates/pubsub/CHANGELOG.md b/crates/pubsub/CHANGELOG.md index 72e4b818fe6..30c35e4ab33 100644 --- a/crates/pubsub/CHANGELOG.md +++ b/crates/pubsub/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Miscellaneous Tasks diff --git a/crates/rpc-client/CHANGELOG.md b/crates/rpc-client/CHANGELOG.md index da0bfa222af..de093c010a4 100644 --- a/crates/rpc-client/CHANGELOG.md +++ b/crates/rpc-client/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Bump tower to 0.5 ([#1249](https://github.com/alloy-rs/alloy/issues/1249)) +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Miscellaneous Tasks diff --git a/crates/rpc-types-admin/CHANGELOG.md b/crates/rpc-types-admin/CHANGELOG.md index 4e4faf9aa82..e40713a2f82 100644 --- a/crates/rpc-types-admin/CHANGELOG.md +++ b/crates/rpc-types-admin/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Miscellaneous Tasks diff --git a/crates/rpc-types-anvil/CHANGELOG.md b/crates/rpc-types-anvil/CHANGELOG.md index e233404cfac..30d7a7cb211 100644 --- a/crates/rpc-types-anvil/CHANGELOG.md +++ b/crates/rpc-types-anvil/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Miscellaneous Tasks diff --git a/crates/rpc-types-beacon/CHANGELOG.md b/crates/rpc-types-beacon/CHANGELOG.md index 5aa55bb9cac..05b74f0e163 100644 --- a/crates/rpc-types-beacon/CHANGELOG.md +++ b/crates/rpc-types-beacon/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.2 - Add helpers for beacon blob bundle ([#1254](https://github.com/alloy-rs/alloy/issues/1254)) ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 diff --git a/crates/rpc-types-debug/CHANGELOG.md b/crates/rpc-types-debug/CHANGELOG.md index 826872ddb63..e1b76917f12 100644 --- a/crates/rpc-types-debug/CHANGELOG.md +++ b/crates/rpc-types-debug/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Miscellaneous Tasks diff --git a/crates/rpc-types-engine/CHANGELOG.md b/crates/rpc-types-engine/CHANGELOG.md index cb79cec60ce..39cfd483a77 100644 --- a/crates/rpc-types-engine/CHANGELOG.md +++ b/crates/rpc-types-engine/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [rpc-types-engine] Add forkchoice state zero helpers ([#1231](https://github.com/alloy-rs/alloy/issues/1231)) +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Miscellaneous Tasks diff --git a/crates/rpc-types-eth/CHANGELOG.md b/crates/rpc-types-eth/CHANGELOG.md index 829e58d9b88..91abad35d20 100644 --- a/crates/rpc-types-eth/CHANGELOG.md +++ b/crates/rpc-types-eth/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Require destination for 7702 ([#1262](https://github.com/alloy-rs/alloy/issues/1262)) + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Bug Fixes @@ -17,6 +23,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [rpc-types-eth] AnyBlock ([#1243](https://github.com/alloy-rs/alloy/issues/1243)) - [network-primitives] Expose more fields via block response traits ([#1229](https://github.com/alloy-rs/alloy/issues/1229)) +### Miscellaneous Tasks + +- Release 0.3.2 + ### Other - Add getter trait methods to `ReceiptResponse` ([#1251](https://github.com/alloy-rs/alloy/issues/1251)) diff --git a/crates/rpc-types-mev/CHANGELOG.md b/crates/rpc-types-mev/CHANGELOG.md index e2ab6c42dfb..9155ac895a6 100644 --- a/crates/rpc-types-mev/CHANGELOG.md +++ b/crates/rpc-types-mev/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Miscellaneous Tasks diff --git a/crates/rpc-types-trace/CHANGELOG.md b/crates/rpc-types-trace/CHANGELOG.md index bff8435c76a..9c973121fa3 100644 --- a/crates/rpc-types-trace/CHANGELOG.md +++ b/crates/rpc-types-trace/CHANGELOG.md @@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Bug Fixes + +- [rpc-types-trace] Use rpc-types Log in OtsReceipt ([#1261](https://github.com/alloy-rs/alloy/issues/1261)) + +### Features + +- [rpc-types-trace] Always serialize result if no error ([#1258](https://github.com/alloy-rs/alloy/issues/1258)) + +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Miscellaneous Tasks diff --git a/crates/rpc-types-txpool/CHANGELOG.md b/crates/rpc-types-txpool/CHANGELOG.md index 5ccb69008e5..34804304166 100644 --- a/crates/rpc-types-txpool/CHANGELOG.md +++ b/crates/rpc-types-txpool/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Miscellaneous Tasks diff --git a/crates/rpc-types/CHANGELOG.md b/crates/rpc-types/CHANGELOG.md index 6d02ddb0e54..3712b7274a8 100644 --- a/crates/rpc-types/CHANGELOG.md +++ b/crates/rpc-types/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Miscellaneous Tasks diff --git a/crates/serde/CHANGELOG.md b/crates/serde/CHANGELOG.md index da2025dea45..1c4ea73de15 100644 --- a/crates/serde/CHANGELOG.md +++ b/crates/serde/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Miscellaneous Tasks diff --git a/crates/signer-aws/CHANGELOG.md b/crates/signer-aws/CHANGELOG.md index 3d44aeda1e5..425f689aa40 100644 --- a/crates/signer-aws/CHANGELOG.md +++ b/crates/signer-aws/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Miscellaneous Tasks diff --git a/crates/signer-gcp/CHANGELOG.md b/crates/signer-gcp/CHANGELOG.md index ee852b83c1b..f4fbcb20723 100644 --- a/crates/signer-gcp/CHANGELOG.md +++ b/crates/signer-gcp/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Miscellaneous Tasks diff --git a/crates/signer-ledger/CHANGELOG.md b/crates/signer-ledger/CHANGELOG.md index dcdd290a995..ff9c08f2d01 100644 --- a/crates/signer-ledger/CHANGELOG.md +++ b/crates/signer-ledger/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Miscellaneous Tasks diff --git a/crates/signer-local/CHANGELOG.md b/crates/signer-local/CHANGELOG.md index 0d12e814519..1f750484ca2 100644 --- a/crates/signer-local/CHANGELOG.md +++ b/crates/signer-local/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Miscellaneous Tasks diff --git a/crates/signer-trezor/CHANGELOG.md b/crates/signer-trezor/CHANGELOG.md index 68e91178338..caf1d6ec28f 100644 --- a/crates/signer-trezor/CHANGELOG.md +++ b/crates/signer-trezor/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Miscellaneous Tasks diff --git a/crates/signer/CHANGELOG.md b/crates/signer/CHANGELOG.md index bbe1a19359f..86526cebe52 100644 --- a/crates/signer/CHANGELOG.md +++ b/crates/signer/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Miscellaneous Tasks diff --git a/crates/transport-http/CHANGELOG.md b/crates/transport-http/CHANGELOG.md index 1b69a3ffac1..a6adeaf56a4 100644 --- a/crates/transport-http/CHANGELOG.md +++ b/crates/transport-http/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Miscellaneous Tasks diff --git a/crates/transport-ipc/CHANGELOG.md b/crates/transport-ipc/CHANGELOG.md index e646f8a0229..d9769994646 100644 --- a/crates/transport-ipc/CHANGELOG.md +++ b/crates/transport-ipc/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Miscellaneous Tasks diff --git a/crates/transport-ws/CHANGELOG.md b/crates/transport-ws/CHANGELOG.md index 24f4f510f0c..86935a70de6 100644 --- a/crates/transport-ws/CHANGELOG.md +++ b/crates/transport-ws/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Miscellaneous Tasks diff --git a/crates/transport/CHANGELOG.md b/crates/transport/CHANGELOG.md index d448e84917f..9bf42aaafb7 100644 --- a/crates/transport/CHANGELOG.md +++ b/crates/transport/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 + +### Miscellaneous Tasks + +- Release 0.3.2 + ## [0.3.1](https://github.com/alloy-rs/alloy/releases/tag/v0.3.1) - 2024-09-02 ### Miscellaneous Tasks From 75d4d0c69a164699f3dd30baea497564d198c1a0 Mon Sep 17 00:00:00 2001 From: refcell Date: Tue, 10 Sep 2024 09:51:41 -0400 Subject: [PATCH 154/186] chore(network-primitives): Remove alloc Vec Dep (#1267) --- crates/network-primitives/src/traits.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/crates/network-primitives/src/traits.rs b/crates/network-primitives/src/traits.rs index 03f5fdf2598..53a8ef39703 100644 --- a/crates/network-primitives/src/traits.rs +++ b/crates/network-primitives/src/traits.rs @@ -4,9 +4,6 @@ use alloy_serde::WithOtherFields; use crate::BlockTransactions; -#[cfg(not(feature = "std"))] -use alloc::vec::Vec; - /// Receipt JSON-RPC response. pub trait ReceiptResponse { /// Address of the created contract, or `None` if the transaction was not a deployment. From c9e8263dadd25c7f0eb7a75dc2e4c626c52f41e5 Mon Sep 17 00:00:00 2001 From: refcell Date: Tue, 10 Sep 2024 19:55:27 -0400 Subject: [PATCH 155/186] chore(consensus): Alloc by Default (#1272) fix: remove the feature flag for alloc --- crates/consensus/src/header.rs | 4 +--- crates/consensus/src/lib.rs | 1 - crates/consensus/src/receipt/receipts.rs | 4 +--- crates/consensus/src/transaction/eip1559.rs | 4 +--- crates/consensus/src/transaction/eip2930.rs | 4 +--- crates/consensus/src/transaction/eip4844.rs | 4 +--- crates/consensus/src/transaction/eip7702.rs | 10 +++++----- crates/consensus/src/transaction/legacy.rs | 4 +--- crates/consensus/src/transaction/mod.rs | 4 +--- 9 files changed, 12 insertions(+), 27 deletions(-) diff --git a/crates/consensus/src/header.rs b/crates/consensus/src/header.rs index 55045b03dc0..b36ee7bf0b1 100644 --- a/crates/consensus/src/header.rs +++ b/crates/consensus/src/header.rs @@ -1,3 +1,4 @@ +use alloc::vec::Vec; use alloy_eips::{ eip1559::{calc_next_block_base_fee, BaseFeeParams}, eip4844::{calc_blob_gasprice, calc_excess_blob_gas}, @@ -12,9 +13,6 @@ use alloy_rlp::{ }; use core::mem; -#[cfg(not(feature = "std"))] -use alloc::vec::Vec; - /// Ommer root of empty list. pub const EMPTY_OMMER_ROOT_HASH: B256 = b256!("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"); diff --git a/crates/consensus/src/lib.rs b/crates/consensus/src/lib.rs index 5fd91a76559..65ec35a908f 100644 --- a/crates/consensus/src/lib.rs +++ b/crates/consensus/src/lib.rs @@ -7,7 +7,6 @@ #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] #![cfg_attr(not(feature = "std"), no_std)] -#[cfg(not(feature = "std"))] extern crate alloc; mod account; diff --git a/crates/consensus/src/receipt/receipts.rs b/crates/consensus/src/receipt/receipts.rs index e9476a81f72..63fa657e5d7 100644 --- a/crates/consensus/src/receipt/receipts.rs +++ b/crates/consensus/src/receipt/receipts.rs @@ -1,11 +1,9 @@ use crate::receipt::{Eip658Value, TxReceipt}; +use alloc::vec::Vec; use alloy_primitives::{Bloom, Log}; use alloy_rlp::{length_of_length, BufMut, Decodable, Encodable}; use core::borrow::Borrow; -#[cfg(not(feature = "std"))] -use alloc::vec::Vec; - /// Receipt containing result of transaction execution. #[derive(Clone, Debug, Default, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Deserialize))] diff --git a/crates/consensus/src/transaction/eip1559.rs b/crates/consensus/src/transaction/eip1559.rs index 3f072cc8a05..108c7e8a4c6 100644 --- a/crates/consensus/src/transaction/eip1559.rs +++ b/crates/consensus/src/transaction/eip1559.rs @@ -1,12 +1,10 @@ use crate::{EncodableSignature, SignableTransaction, Signed, Transaction, TxType}; +use alloc::vec::Vec; use alloy_eips::{eip2930::AccessList, eip7702::SignedAuthorization}; use alloy_primitives::{keccak256, Bytes, ChainId, Signature, TxKind, B256, U256}; use alloy_rlp::{BufMut, Decodable, Encodable, Header}; use core::mem; -#[cfg(not(feature = "std"))] -use alloc::vec::Vec; - /// A transaction with a priority fee ([EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)). #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] diff --git a/crates/consensus/src/transaction/eip2930.rs b/crates/consensus/src/transaction/eip2930.rs index 5917f3d741c..5ed91a2b6f0 100644 --- a/crates/consensus/src/transaction/eip2930.rs +++ b/crates/consensus/src/transaction/eip2930.rs @@ -1,12 +1,10 @@ use crate::{EncodableSignature, SignableTransaction, Signed, Transaction, TxType}; +use alloc::vec::Vec; use alloy_eips::{eip2930::AccessList, eip7702::SignedAuthorization}; use alloy_primitives::{keccak256, Bytes, ChainId, Signature, TxKind, B256, U256}; use alloy_rlp::{length_of_length, BufMut, Decodable, Encodable, Header}; use core::mem; -#[cfg(not(feature = "std"))] -use alloc::vec::Vec; - /// Transaction with an [`AccessList`] ([EIP-2930](https://eips.ethereum.org/EIPS/eip-2930)). #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] diff --git a/crates/consensus/src/transaction/eip4844.rs b/crates/consensus/src/transaction/eip4844.rs index a4775200952..78bb4d28650 100644 --- a/crates/consensus/src/transaction/eip4844.rs +++ b/crates/consensus/src/transaction/eip4844.rs @@ -1,5 +1,6 @@ use crate::{EncodableSignature, SignableTransaction, Signed, Transaction, TxType}; +use alloc::vec::Vec; use alloy_eips::{eip2930::AccessList, eip4844::DATA_GAS_PER_BLOB, eip7702::SignedAuthorization}; use alloy_primitives::{keccak256, Address, Bytes, ChainId, Signature, TxKind, B256, U256}; use alloy_rlp::{length_of_length, BufMut, Decodable, Encodable, Header}; @@ -12,9 +13,6 @@ pub use alloy_eips::eip4844::BlobTransactionSidecar; #[doc(inline)] pub use alloy_eips::eip4844::BlobTransactionValidationError; -#[cfg(not(feature = "std"))] -use alloc::vec::Vec; - /// [EIP-4844 Blob Transaction](https://eips.ethereum.org/EIPS/eip-4844#blob-transaction) /// /// A transaction with blob hashes and max blob fee. diff --git a/crates/consensus/src/transaction/eip7702.rs b/crates/consensus/src/transaction/eip7702.rs index a0dc1fde7e1..c13bda3bf98 100644 --- a/crates/consensus/src/transaction/eip7702.rs +++ b/crates/consensus/src/transaction/eip7702.rs @@ -1,13 +1,13 @@ use crate::{EncodableSignature, SignableTransaction, Signed, Transaction, TxType}; -use alloy_eips::eip2930::AccessList; +use alloc::vec::Vec; +use alloy_eips::{ + eip2930::AccessList, + eip7702::{constants::EIP7702_TX_TYPE_ID, SignedAuthorization}, +}; use alloy_primitives::{keccak256, Address, Bytes, ChainId, Signature, TxKind, B256, U256}; use alloy_rlp::{BufMut, Decodable, Encodable, Header}; use core::mem; -#[cfg(not(feature = "std"))] -use alloc::vec::Vec; -use alloy_eips::eip7702::{constants::EIP7702_TX_TYPE_ID, SignedAuthorization}; - /// A transaction with a priority fee ([EIP-7702](https://eips.ethereum.org/EIPS/eip-7702)). #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] diff --git a/crates/consensus/src/transaction/legacy.rs b/crates/consensus/src/transaction/legacy.rs index e212f93bc6d..c3ecdc5437c 100644 --- a/crates/consensus/src/transaction/legacy.rs +++ b/crates/consensus/src/transaction/legacy.rs @@ -1,14 +1,12 @@ use core::mem; +use alloc::vec::Vec; use alloy_eips::{eip2930::AccessList, eip7702::SignedAuthorization}; use alloy_primitives::{keccak256, Bytes, ChainId, Signature, TxKind, B256, U256}; use alloy_rlp::{length_of_length, BufMut, Decodable, Encodable, Header, Result}; use crate::{EncodableSignature, SignableTransaction, Signed, Transaction, TxType}; -#[cfg(not(feature = "std"))] -use alloc::vec::Vec; - /// Legacy transaction. #[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] diff --git a/crates/consensus/src/transaction/mod.rs b/crates/consensus/src/transaction/mod.rs index a4bf0ebd401..64d6edd7935 100644 --- a/crates/consensus/src/transaction/mod.rs +++ b/crates/consensus/src/transaction/mod.rs @@ -1,13 +1,11 @@ //! Transaction types. use crate::Signed; +use alloc::vec::Vec; use alloy_eips::{eip2930::AccessList, eip7702::SignedAuthorization}; use alloy_primitives::{keccak256, ChainId, TxKind, B256, U256}; use core::any; -#[cfg(not(feature = "std"))] -use alloc::vec::Vec; - mod eip1559; pub use eip1559::TxEip1559; From 30897cca8c2424ee38776950af3ccec2e1179f64 Mon Sep 17 00:00:00 2001 From: refcell Date: Tue, 10 Sep 2024 19:56:03 -0400 Subject: [PATCH 156/186] chore(consensus): Remove Header Method (#1271) chore: remove unnused header commented method --- crates/consensus/src/header.rs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/crates/consensus/src/header.rs b/crates/consensus/src/header.rs index b36ee7bf0b1..a635ba0654c 100644 --- a/crates/consensus/src/header.rs +++ b/crates/consensus/src/header.rs @@ -174,13 +174,6 @@ impl Sealable for Header { } impl Header { - // TODO: re-enable - - // /// Returns the parent block's number and hash - // pub fn parent_num_hash(&self) -> BlockNumHash { - // BlockNumHash { number: self.number.saturating_sub(1), hash: self.parent_hash } - // } - /// Heavy function that will calculate hash of data and will *not* save the change to metadata. /// /// Use [`Header::seal_slow`] and unlock if you need the hash to be persistent. From 043dc2066f9590ccece6fea037fb9be287ddbdfd Mon Sep 17 00:00:00 2001 From: Thomas Coratger <60488569+tcoratger@users.noreply.github.com> Date: Tue, 10 Sep 2024 16:58:51 -0700 Subject: [PATCH 157/186] consensus: implement `seal` helper for `Header` (#1269) * consensus: implement seal helper for Header * fix clippy --- crates/consensus/src/header.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/crates/consensus/src/header.rs b/crates/consensus/src/header.rs index a635ba0654c..3109d9044e3 100644 --- a/crates/consensus/src/header.rs +++ b/crates/consensus/src/header.rs @@ -6,7 +6,7 @@ use alloy_eips::{ BlockNumHash, }; use alloy_primitives::{ - b256, keccak256, Address, BlockNumber, Bloom, Bytes, Sealable, B256, B64, U256, + b256, keccak256, Address, BlockNumber, Bloom, Bytes, Sealable, Sealed, B256, B64, U256, }; use alloy_rlp::{ length_of_length, Buf, BufMut, Decodable, Encodable, EMPTY_LIST_CODE, EMPTY_STRING_CODE, @@ -370,6 +370,14 @@ impl Header { pub const fn exceeds_allowed_future_timestamp(&self, present_timestamp: u64) -> bool { self.timestamp > present_timestamp + ALLOWED_FUTURE_BLOCK_TIME_SECONDS } + + /// Seal the header with a known hash. + /// + /// WARNING: This method does not perform validation whether the hash is correct. + #[inline] + pub const fn seal(self, hash: B256) -> Sealed { + Sealed::new_unchecked(self, hash) + } } impl Encodable for Header { From 5354223a22f9eca76df6697aefa165d8c48006cc Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Wed, 11 Sep 2024 04:25:02 +0400 Subject: [PATCH 158/186] fix: serde for `eth_simulateV1` (#1273) * fix: serde for eth_simulateV1 * clippy + fmt --- crates/provider/src/fillers/nonce.rs | 2 + crates/rpc-types-eth/src/simulate.rs | 63 ++++++++++++---------------- crates/rpc-types-eth/src/state.rs | 5 +++ 3 files changed, 33 insertions(+), 37 deletions(-) diff --git a/crates/provider/src/fillers/nonce.rs b/crates/provider/src/fillers/nonce.rs index 273499bab72..ad81f83ac13 100644 --- a/crates/provider/src/fillers/nonce.rs +++ b/crates/provider/src/fillers/nonce.rs @@ -46,6 +46,8 @@ impl NonceManager for SimpleNonceManager { } } +/// Cached nonce manager +/// /// This [`NonceManager`] implementation will fetch the transaction count for any new account it /// sees, store it locally and increment the locally stored nonce as transactions are sent via /// [`Provider::send_transaction`]. diff --git a/crates/rpc-types-eth/src/simulate.rs b/crates/rpc-types-eth/src/simulate.rs index be61122456c..c27750449c1 100644 --- a/crates/rpc-types-eth/src/simulate.rs +++ b/crates/rpc-types-eth/src/simulate.rs @@ -1,9 +1,9 @@ //! 'eth_simulateV1' Request / Response types: -use alloy_primitives::{Address, Bytes, Log, B256}; +use alloy_primitives::Bytes; use serde::{Deserialize, Serialize}; -use crate::{state::StateOverride, BlockOverrides, TransactionRequest}; +use crate::{state::StateOverride, Block, BlockOverrides, Log, TransactionRequest}; /// The maximum number of blocks that can be simulated in a single request, pub const MAX_SIMULATE_BLOCKS: u64 = 256; @@ -15,47 +15,26 @@ pub const MAX_SIMULATE_BLOCKS: u64 = 256; #[serde(rename_all = "camelCase")] pub struct SimBlock { /// Modifications to the default block characteristics. - pub block_overrides: BlockOverrides, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub block_overrides: Option, /// State modifications to apply before executing the transactions. - pub state_overrides: StateOverride, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub state_overrides: Option, /// A vector of transactions to be simulated. pub calls: Vec, } + /// Represents the result of simulating a block. #[derive(Clone, Debug, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] -pub struct SimulatedBlock { - /// The number of the block. - #[serde(with = "alloy_serde::quantity")] - pub number: u64, - /// The hash of the block. - pub hash: B256, - /// The timestamp of the block. - #[serde(with = "alloy_serde::quantity")] - pub timestamp: u64, - /// The gas limit of the block. - #[serde(with = "alloy_serde::quantity")] - pub gas_limit: u64, - /// The amount of gas used in the block. - #[serde(with = "alloy_serde::quantity")] - pub gas_used: u64, - /// The recipient of the block's fees. - pub fee_recipient: Address, - /// The base fee per gas unit for the block. - #[serde(with = "alloy_serde::quantity")] - pub base_fee_per_gas: u64, - /// The previous RANDAO value of the block. - pub prev_randao: B256, +pub struct SimulatedBlock { + /// The simulated block. + #[serde(flatten)] + pub inner: B, /// A vector of results for each call in the block. pub calls: Vec, } -/// The response type for the eth_simulateV1 method. -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct SimulateV1Response { - /// Simulated blocks vector. - pub simulated_blocks: Vec, -} + /// Captures the outcome of a transaction simulation. /// It includes the return value, logs produced, gas used, and the status of the transaction. #[derive(Clone, Debug, Serialize, Deserialize)] @@ -71,7 +50,7 @@ pub struct SimCallResult { pub gas_used: u64, /// The final status of the transaction, typically indicating success or failure. #[serde(with = "alloy_serde::quantity")] - pub status: u64, + pub status: bool, /// Error in case the call failed #[serde(default, skip_serializing_if = "Option::is_none")] pub error: Option, @@ -168,11 +147,21 @@ mod tests { assert_eq!(sim_opts.block_state_calls.len(), 2); let block_state_call_1 = &sim_opts.block_state_calls[0]; - assert!(block_state_call_1.state_overrides.contains_key(&address_1)); - assert_eq!(block_state_call_1.state_overrides.get(&address_1).unwrap().nonce.unwrap(), 5); + assert!(block_state_call_1.state_overrides.as_ref().unwrap().contains_key(&address_1)); + assert_eq!( + block_state_call_1 + .state_overrides + .as_ref() + .unwrap() + .get(&address_1) + .unwrap() + .nonce + .unwrap(), + 5 + ); let block_state_call_2 = &sim_opts.block_state_calls[1]; - assert!(block_state_call_2.state_overrides.contains_key(&address_1)); + assert!(block_state_call_2.state_overrides.as_ref().unwrap().contains_key(&address_1)); assert_eq!(block_state_call_2.calls.len(), 2); assert_eq!(block_state_call_2.calls[0].from.unwrap(), address_1); diff --git a/crates/rpc-types-eth/src/state.rs b/crates/rpc-types-eth/src/state.rs index 4746e5368da..ef35c85cf73 100644 --- a/crates/rpc-types-eth/src/state.rs +++ b/crates/rpc-types-eth/src/state.rs @@ -29,6 +29,11 @@ pub struct AccountOverride { /// the call. #[serde(default, skip_serializing_if = "Option::is_none")] pub state_diff: Option>, + /// Moves addresses precompile into the specified address. This move is done before the 'code' + /// override is set. When the specified address is not a precompile, the behaviour is undefined + /// and different clients might behave differently. + #[serde(default, skip_serializing_if = "Option::is_none", rename = "movePrecompileToAddress")] + pub move_precompile_to: Option
, } /// Helper type that bundles various overrides for EVM Execution. From 41b2fd2d6d8dfbf6563306d826014ae8019dd46c Mon Sep 17 00:00:00 2001 From: refcell Date: Wed, 11 Sep 2024 03:51:13 -0400 Subject: [PATCH 159/186] feat: no_std eth rpc types (#1252) * feat: support no_std in alloy-rpc-types-eth * feat: derive_more error * ci: add no-std check * ci: update script * fix: crate collections * fix: fmt * chore: remove unused hash_map re-export --------- Co-authored-by: Matthias Seitz --- .github/workflows/ci.yml | 16 ++-- .github/workflows/no_std.yml | 25 ------ Cargo.toml | 4 + crates/rpc-types-eth/Cargo.toml | 20 +++-- crates/rpc-types-eth/src/account.rs | 2 + crates/rpc-types-eth/src/block.rs | 20 ++++- crates/rpc-types-eth/src/call.rs | 6 ++ crates/rpc-types-eth/src/erc4337.rs | 5 +- crates/rpc-types-eth/src/fee.rs | 6 +- crates/rpc-types-eth/src/filter.rs | 26 +++--- crates/rpc-types-eth/src/index.rs | 3 +- crates/rpc-types-eth/src/lib.rs | 15 ++++ crates/rpc-types-eth/src/pubsub.rs | 1 + crates/rpc-types-eth/src/raw_log.rs | 2 + crates/rpc-types-eth/src/simulate.rs | 4 +- crates/rpc-types-eth/src/state.rs | 4 +- crates/rpc-types-eth/src/syncing.rs | 3 +- crates/rpc-types-eth/src/transaction/error.rs | 82 +++++++++++++------ crates/rpc-types-eth/src/transaction/mod.rs | 4 +- .../rpc-types-eth/src/transaction/receipt.rs | 2 + .../rpc-types-eth/src/transaction/request.rs | 15 +++- .../src/transaction/signature.rs | 4 +- crates/rpc-types-eth/src/work.rs | 2 +- crates/rpc-types-trace/Cargo.toml | 2 +- crates/rpc-types/Cargo.toml | 2 +- scripts/check_no_std.sh | 24 +++--- 26 files changed, 187 insertions(+), 112 deletions(-) delete mode 100644 .github/workflows/no_std.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 645acbc53a7..bf8b3a3ec63 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -127,33 +127,33 @@ jobs: - name: build ledger run: cargo build -p alloy-signer-ledger --features browser --target wasm32-wasip1 - no-std: + feature-checks: runs-on: ubuntu-latest timeout-minutes: 30 steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable - with: - target: riscv32imac-unknown-none-elf - uses: taiki-e/install-action@cargo-hack - uses: Swatinem/rust-cache@v2 with: cache-on-failure: true - - name: check - run: ./scripts/check_no_std.sh + - name: cargo hack + run: cargo hack check --feature-powerset --depth 1 - feature-checks: + check-no-std: + name: check no_std ${{ matrix.features }} runs-on: ubuntu-latest timeout-minutes: 30 steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable + with: + targets: riscv32imac-unknown-none-elf - uses: taiki-e/install-action@cargo-hack - uses: Swatinem/rust-cache@v2 with: cache-on-failure: true - - name: cargo hack - run: cargo hack check --feature-powerset --depth 1 + - run: ./scripts/check_no_std.sh clippy: runs-on: ubuntu-latest diff --git a/.github/workflows/no_std.yml b/.github/workflows/no_std.yml deleted file mode 100644 index b9af136c279..00000000000 --- a/.github/workflows/no_std.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: no_std - -on: - push: - branches: [main] - pull_request: - -env: - CARGO_TERM_COLOR: always - -jobs: - check-no-std: - name: check no_std ${{ matrix.features }} - runs-on: ubuntu-latest - timeout-minutes: 30 - strategy: - fail-fast: false - matrix: - crate: ["alloy-eips", "alloy-consensus", "alloy-genesis", "alloy-network-primitives"] - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - with: - targets: riscv32imac-unknown-none-elf - - run: cargo check --target riscv32imac-unknown-none-elf --no-default-features -p ${{ matrix.crate }} diff --git a/Cargo.toml b/Cargo.toml index 9ce5c6f391a..c2bb401ac19 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -119,6 +119,10 @@ tower = { version = "0.5", features = ["util"] } tracing = "0.1" tracing-subscriber = "0.3" +# no_std +cfg-if = "1" +hashbrown = "0.14.5" + # misc auto_impl = "1.2" base64 = "0.22" diff --git a/crates/rpc-types-eth/Cargo.toml b/crates/rpc-types-eth/Cargo.toml index e1f36e74051..dde377f60c2 100644 --- a/crates/rpc-types-eth/Cargo.toml +++ b/crates/rpc-types-eth/Cargo.toml @@ -19,19 +19,22 @@ rustdoc-args = ["--cfg", "docsrs"] workspace = true [dependencies] -alloy-rlp = { workspace = true, features = ["arrayvec", "derive"] } -alloy-primitives = { workspace = true, features = ["rlp", "serde", "std"] } alloy-serde.workspace = true - -alloy-consensus = { workspace = true, features = ["serde", "std"] } -alloy-eips = { workspace = true, features = ["serde", "std"] } - alloy-network-primitives.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"] } + +derive_more = { workspace = true, features = ["display"] } itertools.workspace = true serde = { workspace = true, features = ["derive"] } serde_json.workspace = true -thiserror.workspace = true + +# `no_std` compatibility +cfg-if.workspace = true +hashbrown = { workspace = true, features = ["serde"] } # arbitrary arbitrary = { version = "1.3", features = ["derive"], optional = true } @@ -56,7 +59,10 @@ similar-asserts.workspace = true assert_matches.workspace = true [features] +default = ["std"] +std = ["alloy-primitives/std", "alloy-consensus/std", "alloy-eips/std"] arbitrary = [ + "std", "dep:arbitrary", "alloy-primitives/arbitrary", "alloy-serde/arbitrary", diff --git a/crates/rpc-types-eth/src/account.rs b/crates/rpc-types-eth/src/account.rs index 439e24dd5a3..26544f6a0ab 100644 --- a/crates/rpc-types-eth/src/account.rs +++ b/crates/rpc-types-eth/src/account.rs @@ -2,6 +2,8 @@ use alloy_primitives::{Address, Bytes, B256, B512, U256}; use alloy_serde::storage::JsonStorageKey; use serde::{Deserialize, Serialize}; +use alloc::{string::String, vec::Vec}; + // re-export account type for `eth_getAccount` pub use alloy_consensus::Account; diff --git a/crates/rpc-types-eth/src/block.rs b/crates/rpc-types-eth/src/block.rs index 5fd1cfa00e3..82aeebe3691 100644 --- a/crates/rpc-types-eth/src/block.rs +++ b/crates/rpc-types-eth/src/block.rs @@ -1,13 +1,15 @@ //! Block RPC types. use crate::{ConversionError, Transaction, Withdrawal}; +use alloc::collections::BTreeMap; use alloy_network_primitives::{ BlockResponse, BlockTransactions, HeaderResponse, TransactionResponse, }; use alloy_primitives::{Address, BlockHash, Bloom, Bytes, B256, B64, U256}; use alloy_serde::WithOtherFields; use serde::{Deserialize, Serialize}; -use std::collections::BTreeMap; + +use alloc::vec::Vec; pub use alloy_eips::{ calc_blob_gasprice, calc_excess_blob_gas, BlockHashOrNumber, BlockId, BlockNumHash, @@ -247,16 +249,26 @@ impl HeaderResponse for Header { } /// Error that can occur when converting other types to blocks -#[derive(Clone, Copy, Debug, thiserror::Error)] +#[derive(Clone, Copy, Debug, derive_more::Display)] pub enum BlockError { /// A transaction failed sender recovery - #[error("transaction failed sender recovery")] + #[display("transaction failed sender recovery")] InvalidSignature, /// A raw block failed to decode - #[error("failed to decode raw block {0}")] + #[display("failed to decode raw block {_0}")] RlpDecodeRawBlock(alloy_rlp::Error), } +#[cfg(feature = "std")] +impl std::error::Error for BlockError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + Self::RlpDecodeRawBlock(err) => Some(err), + _ => None, + } + } +} + impl From for WithOtherFields { fn from(inner: Block) -> Self { Self { inner, other: Default::default() } diff --git a/crates/rpc-types-eth/src/call.rs b/crates/rpc-types-eth/src/call.rs index 4f4d65c3370..f61775694ef 100644 --- a/crates/rpc-types-eth/src/call.rs +++ b/crates/rpc-types-eth/src/call.rs @@ -2,6 +2,12 @@ use crate::{request::TransactionRequest, BlockId, BlockOverrides}; use alloy_primitives::Bytes; use serde::{Deserialize, Deserializer, Serialize, Serializer}; +use alloc::{ + format, + string::{String, ToString}, + vec::Vec, +}; + /// Bundle of transactions #[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] #[serde(default, rename_all = "camelCase")] diff --git a/crates/rpc-types-eth/src/erc4337.rs b/crates/rpc-types-eth/src/erc4337.rs index a4a3ea201bf..cf73d8d45bf 100644 --- a/crates/rpc-types-eth/src/erc4337.rs +++ b/crates/rpc-types-eth/src/erc4337.rs @@ -1,7 +1,8 @@ -use crate::{Log, TransactionReceipt}; +use crate::{collections::HashMap, Log, TransactionReceipt}; use alloy_primitives::{Address, BlockNumber, Bytes, B256, U256}; use serde::{Deserialize, Serialize}; -use std::collections::HashMap; + +use alloc::vec::Vec; /// Options for conditional raw transaction submissions. // reference for the implementation diff --git a/crates/rpc-types-eth/src/fee.rs b/crates/rpc-types-eth/src/fee.rs index fb01699c4f9..946cfb46605 100644 --- a/crates/rpc-types-eth/src/fee.rs +++ b/crates/rpc-types-eth/src/fee.rs @@ -1,5 +1,7 @@ use serde::{Deserialize, Serialize}; +use alloc::vec::Vec; + /// Internal struct to calculate reward percentiles #[derive(Clone, Copy, Debug, PartialEq, Eq)] #[doc(alias = "TransactionGasAndReward")] @@ -11,13 +13,13 @@ pub struct TxGasAndReward { } impl PartialOrd for TxGasAndReward { - fn partial_cmp(&self, other: &Self) -> Option { + fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } impl Ord for TxGasAndReward { - fn cmp(&self, other: &Self) -> std::cmp::Ordering { + fn cmp(&self, other: &Self) -> core::cmp::Ordering { // compare only the reward // see: // diff --git a/crates/rpc-types-eth/src/filter.rs b/crates/rpc-types-eth/src/filter.rs index ef9ecf1e963..517259a355c 100644 --- a/crates/rpc-types-eth/src/filter.rs +++ b/crates/rpc-types-eth/src/filter.rs @@ -6,15 +6,18 @@ use serde::{ ser::SerializeStruct, Deserialize, Deserializer, Serialize, Serializer, }; -use std::{ - collections::{ - hash_set::{IntoIter, Iter}, - HashSet, - }, + +use alloc::{format, string::String, vec::Vec}; + +use crate::collections::{ + hash_set::{IntoIter, Iter}, + HashSet, +}; +use core::{ hash::Hash, + iter::{FromIterator, IntoIterator}, ops::{RangeFrom, RangeInclusive, RangeToInclusive}, }; -use thiserror::Error; /// Helper type to represent a bloom filter used for matching logs. #[derive(Debug, Default)] @@ -46,7 +49,7 @@ impl From for FilterSet { } impl Hash for FilterSet { - fn hash(&self, state: &mut H) { + fn hash(&self, state: &mut H) { for value in &self.0 { value.hash(state); } @@ -154,10 +157,10 @@ impl From for Topic { } /// Represents errors that can occur when setting block filters in `FilterBlockOption`. -#[derive(Debug, PartialEq, Eq, Error)] +#[derive(Debug, PartialEq, Eq, derive_more::Display)] pub enum FilterBlockError { /// Error indicating that the `from_block` is greater than the `to_block`. - #[error("`from_block` ({from}) is greater than `to_block` ({to})")] + #[display("`from_block` ({from}) is greater than `to_block` ({to})")] FromBlockGreaterThanToBlock { /// The starting block number, which is greater than `to`. from: u64, @@ -166,6 +169,9 @@ pub enum FilterBlockError { }, } +#[cfg(feature = "std")] +impl std::error::Error for FilterBlockError {} + /// Represents the target range of blocks for the filter #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum FilterBlockOption { @@ -593,7 +599,7 @@ impl<'de> Deserialize<'de> for Filter { impl<'de> Visitor<'de> for FilterVisitor { type Value = Filter; - fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { formatter.write_str("Filter object") } diff --git a/crates/rpc-types-eth/src/index.rs b/crates/rpc-types-eth/src/index.rs index b1183c9dc15..b583578670b 100644 --- a/crates/rpc-types-eth/src/index.rs +++ b/crates/rpc-types-eth/src/index.rs @@ -1,9 +1,10 @@ +use alloc::{format, string::String}; use alloy_primitives::U256; +use core::fmt; use serde::{ de::{Error, Visitor}, Deserialize, Deserializer, Serialize, Serializer, }; -use std::fmt; /// A hex encoded or decimal index that's intended to be used as a rust index, hence it's /// deserialized into a `usize`. diff --git a/crates/rpc-types-eth/src/lib.rs b/crates/rpc-types-eth/src/lib.rs index 14e020683df..c39a1a2c124 100644 --- a/crates/rpc-types-eth/src/lib.rs +++ b/crates/rpc-types-eth/src/lib.rs @@ -5,6 +5,21 @@ )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#![cfg_attr(not(any(test, feature = "std")), no_std)] + +extern crate alloc; + +/// Standardized collections across `std` and `no_std` environments. +pub mod collections { + cfg_if::cfg_if! { + if #[cfg(feature = "std")] { + pub use std::collections::{hash_set, HashMap, HashSet}; + use hashbrown as _; + } else { + pub use hashbrown::{hash_set, HashMap, HashSet}; + } + } +} pub use alloy_eips::eip4895::Withdrawal; diff --git a/crates/rpc-types-eth/src/pubsub.rs b/crates/rpc-types-eth/src/pubsub.rs index b5e2dc512e7..f6e1ea335f2 100644 --- a/crates/rpc-types-eth/src/pubsub.rs +++ b/crates/rpc-types-eth/src/pubsub.rs @@ -1,6 +1,7 @@ //! Ethereum types for pub-sub use crate::{Filter, Header, Log, Transaction}; +use alloc::{boxed::Box, format}; use alloy_primitives::B256; use alloy_serde::WithOtherFields; use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer}; diff --git a/crates/rpc-types-eth/src/raw_log.rs b/crates/rpc-types-eth/src/raw_log.rs index c1b3df43c47..53a13081d7e 100644 --- a/crates/rpc-types-eth/src/raw_log.rs +++ b/crates/rpc-types-eth/src/raw_log.rs @@ -3,6 +3,8 @@ use alloy_primitives::{Address, Bloom, Bytes, B256}; use alloy_rlp::{RlpDecodable, RlpEncodable}; +use alloc::vec::Vec; + /// Ethereum Log #[derive(Clone, Debug, Default, PartialEq, Eq, RlpDecodable, RlpEncodable)] pub struct Log { diff --git a/crates/rpc-types-eth/src/simulate.rs b/crates/rpc-types-eth/src/simulate.rs index c27750449c1..e325c89ca37 100644 --- a/crates/rpc-types-eth/src/simulate.rs +++ b/crates/rpc-types-eth/src/simulate.rs @@ -1,10 +1,10 @@ //! 'eth_simulateV1' Request / Response types: +use crate::{state::StateOverride, Block, BlockOverrides, Log, TransactionRequest}; +use alloc::{string::String, vec::Vec}; use alloy_primitives::Bytes; use serde::{Deserialize, Serialize}; -use crate::{state::StateOverride, Block, BlockOverrides, Log, TransactionRequest}; - /// The maximum number of blocks that can be simulated in a single request, pub const MAX_SIMULATE_BLOCKS: u64 = 256; diff --git a/crates/rpc-types-eth/src/state.rs b/crates/rpc-types-eth/src/state.rs index ef35c85cf73..e9ee08511ee 100644 --- a/crates/rpc-types-eth/src/state.rs +++ b/crates/rpc-types-eth/src/state.rs @@ -1,9 +1,9 @@ //! bindings for state overrides in eth_call -use crate::BlockOverrides; +use crate::{collections::HashMap, BlockOverrides}; +use alloc::boxed::Box; use alloy_primitives::{Address, Bytes, B256, U256}; use serde::{Deserialize, Serialize}; -use std::collections::HashMap; /// A set of account overrides pub type StateOverride = HashMap; diff --git a/crates/rpc-types-eth/src/syncing.rs b/crates/rpc-types-eth/src/syncing.rs index f2fda6fdf17..2bfb26824d3 100644 --- a/crates/rpc-types-eth/src/syncing.rs +++ b/crates/rpc-types-eth/src/syncing.rs @@ -1,6 +1,7 @@ use alloy_primitives::{B512, U256}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use std::collections::BTreeMap; + +use alloc::{boxed::Box, collections::BTreeMap, string::String, vec::Vec}; /// Syncing info #[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] diff --git a/crates/rpc-types-eth/src/transaction/error.rs b/crates/rpc-types-eth/src/transaction/error.rs index b285cbb48a4..fdd90502512 100644 --- a/crates/rpc-types-eth/src/transaction/error.rs +++ b/crates/rpc-types-eth/src/transaction/error.rs @@ -1,73 +1,103 @@ -use std::num::TryFromIntError; +use core::num::TryFromIntError; + +use alloc::string::String; /// Error variants when converting from [crate::Transaction] to [alloy_consensus::Signed] /// transaction. -#[derive(Debug, thiserror::Error)] +#[derive(Debug, derive_more::Display)] pub enum ConversionError { /// Error during EIP-2718 transaction coding. - #[error(transparent)] - Eip2718Error(#[from] alloy_eips::eip2718::Eip2718Error), + #[display("{_0}")] + Eip2718Error(alloy_eips::eip2718::Eip2718Error), /// [`alloy_primitives::SignatureError`]. - #[error(transparent)] - SignatureError(#[from] alloy_primitives::SignatureError), + #[display("{_0}")] + SignatureError(alloy_primitives::SignatureError), /// Missing signature for transaction. - #[error("missing signature for transaction")] + #[display("missing signature for transaction")] MissingSignature, /// Missing y parity in signature. - #[error("missing y parity in signature")] + #[display("missing y parity in signature")] MissingYParity, /// Invalid signature - #[error("invalid signature")] + #[display("invalid signature")] InvalidSignature, /// Missing `chainId` field for EIP-1559 transaction. - #[error("missing `chainId` field for EIP-155 transaction")] + #[display("missing `chainId` field for EIP-155 transaction")] MissingChainId, /// Missing `gasPrice` field for Legacy transaction. - #[error("missing `gasPrice` field for Legacy transaction")] + #[display("missing `gasPrice` field for Legacy transaction")] MissingGasPrice, /// Missing `accessList` field for EIP-2930 transaction. - #[error("missing `accessList` field for EIP-2930 transaction")] + #[display("missing `accessList` field for EIP-2930 transaction")] MissingAccessList, /// Missing `maxFeePerGas` field for EIP-1559 transaction. - #[error("missing `maxFeePerGas` field for EIP-1559 transaction")] + #[display("missing `maxFeePerGas` field for EIP-1559 transaction")] MissingMaxFeePerGas, /// Missing `maxPriorityFeePerGas` field for EIP-1559 transaction. - #[error("missing `maxPriorityFeePerGas` field for EIP-1559 transaction")] + #[display("missing `maxPriorityFeePerGas` field for EIP-1559 transaction")] MissingMaxPriorityFeePerGas, /// Missing `maxFeePerBlobGas` field for EIP-1559 transaction. - #[error("missing `maxFeePerBlobGas` field for EIP-1559 transaction")] + #[display("missing `maxFeePerBlobGas` field for EIP-1559 transaction")] MissingMaxFeePerBlobGas, /// Missing `to` field for EIP-4844 transaction. - #[error("missing `to` field for EIP-4844 transaction")] + #[display("missing `to` field for EIP-4844 transaction")] MissingTo, /// Missing `blobVersionedHashes` field for EIP-4844 transaction. - #[error("missing `blobVersionedHashes` field for EIP-4844 transaction")] + #[display("missing `blobVersionedHashes` field for EIP-4844 transaction")] MissingBlobVersionedHashes, /// Missing `authorizationList` field for EIP-7702 transaction. - #[error("missing `authorizationList` field for EIP-7702 transaction")] + #[display("missing `authorizationList` field for EIP-7702 transaction")] MissingAuthorizationList, /// Missing full transactions required for block decoding - #[error("missing full transactions required for block decoding")] + #[display("missing full transactions required for block decoding")] MissingFullTransactions, /// Base fee per gas integer conversion error - #[error("base fee per gas integer conversion error: {0}")] + #[display("base fee per gas integer conversion error: {_0}")] BaseFeePerGasConversion(TryFromIntError), /// Gas limit integer conversion error - #[error("gas limit integer conversion error: {0}")] + #[display("gas limit integer conversion error: {_0}")] GasLimitConversion(TryFromIntError), /// Gas used integer conversion error - #[error("gas used integer conversion error: {0}")] + #[display("gas used integer conversion error: {_0}")] GasUsedConversion(TryFromIntError), /// Missing block number - #[error("missing block number")] + #[display("missing block number")] MissingBlockNumber, /// Blob gas used integer conversion error - #[error("blob gas used integer conversion error: {0}")] + #[display("blob gas used integer conversion error: {_0}")] BlobGasUsedConversion(TryFromIntError), /// Excess blob gas integer conversion error - #[error("excess blob gas integer conversion error: {0}")] + #[display("excess blob gas integer conversion error: {_0}")] ExcessBlobGasConversion(TryFromIntError), /// A custom Conversion Error that doesn't fit other categories. - #[error("conversion error: {0}")] + #[display("conversion error: {_0}")] Custom(String), } + +#[cfg(feature = "std")] +impl std::error::Error for ConversionError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + Self::Eip2718Error(err) => Some(err), + Self::SignatureError(err) => Some(err), + Self::BaseFeePerGasConversion(err) => Some(err), + Self::GasLimitConversion(err) => Some(err), + Self::GasUsedConversion(err) => Some(err), + Self::BlobGasUsedConversion(err) => Some(err), + Self::ExcessBlobGasConversion(err) => Some(err), + _ => None, + } + } +} + +impl From for ConversionError { + fn from(err: alloy_eips::eip2718::Eip2718Error) -> Self { + Self::Eip2718Error(err) + } +} + +impl From for ConversionError { + fn from(err: alloy_primitives::SignatureError) -> Self { + Self::SignatureError(err) + } +} diff --git a/crates/rpc-types-eth/src/transaction/mod.rs b/crates/rpc-types-eth/src/transaction/mod.rs index 1700bcf33bd..3a46cfb3cc2 100644 --- a/crates/rpc-types-eth/src/transaction/mod.rs +++ b/crates/rpc-types-eth/src/transaction/mod.rs @@ -9,6 +9,8 @@ use alloy_network_primitives::TransactionResponse; use alloy_primitives::{Address, BlockHash, Bytes, ChainId, TxHash, TxKind, B256, U256}; use serde::{Deserialize, Serialize}; +use alloc::vec::Vec; + pub use alloy_consensus::BlobTransactionSidecar; pub use alloy_eips::{ eip2930::{AccessList, AccessListItem, AccessListResult}, @@ -325,8 +327,8 @@ mod tests { use super::*; use alloy_primitives::Signature as AlloySignature; use arbitrary::Arbitrary; + use core::str::FromStr; use rand::Rng; - use std::str::FromStr; #[test] fn arbitrary_transaction() { diff --git a/crates/rpc-types-eth/src/transaction/receipt.rs b/crates/rpc-types-eth/src/transaction/receipt.rs index 497e89e9d37..8714203ebc1 100644 --- a/crates/rpc-types-eth/src/transaction/receipt.rs +++ b/crates/rpc-types-eth/src/transaction/receipt.rs @@ -6,6 +6,8 @@ use alloy_primitives::{Address, BlockHash, TxHash, B256}; use alloy_serde::WithOtherFields; use serde::{Deserialize, Serialize}; +use alloc::vec::Vec; + /// Transaction receipt /// /// This type is generic over an inner [`ReceiptEnvelope`] which contains diff --git a/crates/rpc-types-eth/src/transaction/request.rs b/crates/rpc-types-eth/src/transaction/request.rs index 0a037d300d2..c7938f5b8ce 100644 --- a/crates/rpc-types-eth/src/transaction/request.rs +++ b/crates/rpc-types-eth/src/transaction/request.rs @@ -7,8 +7,14 @@ use alloy_consensus::{ }; use alloy_eips::eip7702::SignedAuthorization; use alloy_primitives::{Address, Bytes, ChainId, TxKind, B256, U256}; +use core::hash::Hash; use serde::{Deserialize, Serialize}; -use std::hash::Hash; + +use alloc::{ + string::{String, ToString}, + vec, + vec::Vec, +}; /// Represents _all_ transaction requests to/from RPC. #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] @@ -930,12 +936,15 @@ impl From for TransactionRequest { } /// Error thrown when both `data` and `input` fields are set and not equal. -#[derive(Debug, Default, thiserror::Error)] -#[error("both \"data\" and \"input\" are set and not equal. Please use \"input\" to pass transaction call data")] +#[derive(Debug, Default, derive_more::Display)] +#[display("both \"data\" and \"input\" are set and not equal. Please use \"input\" to pass transaction call data")] #[doc(alias = "TxInputError")] #[non_exhaustive] pub struct TransactionInputError; +#[cfg(feature = "std")] +impl std::error::Error for TransactionInputError {} + /// Error thrown when a transaction request cannot be built into a transaction. #[derive(Debug)] pub struct BuildTransactionErr { diff --git a/crates/rpc-types-eth/src/transaction/signature.rs b/crates/rpc-types-eth/src/transaction/signature.rs index 5599fc9afc6..8a32476c575 100644 --- a/crates/rpc-types-eth/src/transaction/signature.rs +++ b/crates/rpc-types-eth/src/transaction/signature.rs @@ -2,6 +2,8 @@ use alloy_primitives::U256; use serde::{Deserialize, Serialize}; +use alloc::{format, string::String}; + /// Container type for all signature fields in RPC #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)] @@ -89,7 +91,7 @@ impl From for Signature { #[cfg(test)] mod tests { use super::*; - use std::str::FromStr; + use core::str::FromStr; #[test] fn deserialize_without_parity() { diff --git a/crates/rpc-types-eth/src/work.rs b/crates/rpc-types-eth/src/work.rs index b0d2a1fb7a3..cf8ec8666a7 100644 --- a/crates/rpc-types-eth/src/work.rs +++ b/crates/rpc-types-eth/src/work.rs @@ -1,9 +1,9 @@ use alloy_primitives::{B256, U256}; +use core::fmt; use serde::{ de::{Error, SeqAccess, Visitor}, Deserialize, Deserializer, Serialize, Serializer, }; -use std::fmt; /// The result of an `eth_getWork` request #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] diff --git a/crates/rpc-types-trace/Cargo.toml b/crates/rpc-types-trace/Cargo.toml index 7181ff4755f..cdd3e7322b8 100644 --- a/crates/rpc-types-trace/Cargo.toml +++ b/crates/rpc-types-trace/Cargo.toml @@ -20,7 +20,7 @@ workspace = true [dependencies] alloy-primitives = { workspace = true, features = ["rlp", "serde"] } -alloy-rpc-types-eth.workspace = true +alloy-rpc-types-eth = { workspace = true, features = ["std"] } alloy-serde.workspace = true serde.workspace = true diff --git a/crates/rpc-types/Cargo.toml b/crates/rpc-types/Cargo.toml index bc5d58e1e27..0027917ddc5 100644 --- a/crates/rpc-types/Cargo.toml +++ b/crates/rpc-types/Cargo.toml @@ -35,7 +35,7 @@ serde = { workspace = true, features = ["derive", "std"] } serde_json.workspace = true [features] -default = ["eth", "alloy-rpc-types-engine?/default"] +default = ["eth", "alloy-rpc-types-engine?/default", "alloy-rpc-types-eth?/default"] admin = ["dep:alloy-rpc-types-admin"] anvil = ["dep:alloy-rpc-types-anvil"] beacon = ["dep:alloy-rpc-types-beacon"] diff --git a/scripts/check_no_std.sh b/scripts/check_no_std.sh index 1aa49ec6d64..dd2f00262e0 100755 --- a/scripts/check_no_std.sh +++ b/scripts/check_no_std.sh @@ -1,24 +1,20 @@ #!/usr/bin/env bash set -eo pipefail -no_std_packages=( +target=riscv32imac-unknown-none-elf +crates=( alloy-eips alloy-genesis alloy-serde alloy-consensus + alloy-network-primitives + alloy-rpc-types-eth ) -for package in "${no_std_packages[@]}"; do - cmd="cargo +stable build -p $package --target riscv32imac-unknown-none-elf --no-default-features" - if [ -n "$CI" ]; then - echo "::group::$cmd" - else - printf "\n%s:\n %s\n" "$package" "$cmd" - fi - - $cmd - - if [ -n "$CI" ]; then - echo "::endgroup::" - fi +cmd=(cargo +stable hack check --no-default-features --target "$target") +for crate in "${crates[@]}"; do + cmd+=(-p "$crate") done + +echo "Running: ${cmd[*]}" +"${cmd[@]}" From 8546ecfe61878632438589f9726ad8a9ae75f887 Mon Sep 17 00:00:00 2001 From: Panagiotis Ganelis <50522617+PanGan21@users.noreply.github.com> Date: Wed, 11 Sep 2024 13:03:00 +0300 Subject: [PATCH 160/186] chore: swap `BlockHashOrNumber` alias and struct name (#1270) * chore: swap struct and alias name for BlockHashOrNumber * chore: update docs --- crates/eips/src/eip1898.rs | 56 +++++++++++++++++++------------------- crates/eips/src/lib.rs | 3 +- 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/crates/eips/src/eip1898.rs b/crates/eips/src/eip1898.rs index 8a298d5a7e6..4b0690f78af 100644 --- a/crates/eips/src/eip1898.rs +++ b/crates/eips/src/eip1898.rs @@ -393,13 +393,13 @@ impl From for BlockId { } } -impl From for BlockId { - fn from(block: BlockHashOrNumber) -> Self { +impl From for BlockId { + fn from(block: HashOrNumber) -> Self { match block { - BlockHashOrNumber::Hash(hash) => { + HashOrNumber::Hash(hash) => { Self::Hash(RpcBlockHash { block_hash: hash, require_canonical: None }) } - BlockHashOrNumber::Number(num) => Self::Number(BlockNumberOrTag::Number(num)), + HashOrNumber::Number(num) => Self::Number(BlockNumberOrTag::Number(num)), } } } @@ -626,11 +626,11 @@ impl NumHash { (self.number, self.hash) } - /// Returns whether or not the block matches the given [BlockHashOrNumber]. - pub fn matches_block_or_num(&self, block: &BlockHashOrNumber) -> bool { + /// Returns whether or not the block matches the given [HashOrNumber]. + pub fn matches_block_or_num(&self, block: &HashOrNumber) -> bool { match block { - BlockHashOrNumber::Hash(hash) => self.hash == *hash, - BlockHashOrNumber::Number(number) => self.number == *number, + HashOrNumber::Hash(hash) => self.hash == *hash, + HashOrNumber::Number(number) => self.number == *number, } } } @@ -647,24 +647,24 @@ impl From<(B256, u64)> for NumHash { } } -/// Either a block hash _or_ a block number +/// Either a hash _or_ a block number #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] -pub enum BlockHashOrNumber { - /// A block hash +pub enum HashOrNumber { + /// The hash Hash(B256), - /// A block number + /// The number Number(u64), } -/// Either a hash _or_ a number -pub type HashOrNumber = BlockHashOrNumber; +/// A block hash _or_ a block number +pub type BlockHashOrNumber = HashOrNumber; -// === impl BlockHashOrNumber === +// === impl HashOrNumber === -impl BlockHashOrNumber { - /// Returns the block number if it is a [`BlockHashOrNumber::Number`]. +impl HashOrNumber { + /// Returns the block number if it is a [`HashOrNumber::Number`]. #[inline] pub const fn as_number(self) -> Option { match self { @@ -674,32 +674,32 @@ impl BlockHashOrNumber { } } -impl From for BlockHashOrNumber { +impl From for HashOrNumber { fn from(value: B256) -> Self { Self::Hash(value) } } -impl From for BlockHashOrNumber { +impl From for HashOrNumber { fn from(value: u64) -> Self { Self::Number(value) } } -impl From for BlockHashOrNumber { +impl From for HashOrNumber { fn from(value: U64) -> Self { value.to::().into() } } -impl From for BlockHashOrNumber { +impl From for HashOrNumber { fn from(value: RpcBlockHash) -> Self { Self::Hash(value.into()) } } -/// Allows for RLP encoding of either a block hash or block number -impl Encodable for BlockHashOrNumber { +/// Allows for RLP encoding of either a hash or a number +impl Encodable for HashOrNumber { fn encode(&self, out: &mut dyn bytes::BufMut) { match self { Self::Hash(block_hash) => block_hash.encode(out), @@ -714,8 +714,8 @@ impl Encodable for BlockHashOrNumber { } } -/// Allows for RLP decoding of a block hash or block number -impl Decodable for BlockHashOrNumber { +/// Allows for RLP decoding of a hash or number +impl Decodable for HashOrNumber { fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { let header: u8 = *buf.first().ok_or(RlpError::InputTooShort)?; // if the byte string is exactly 32 bytes, decode it into a Hash @@ -736,7 +736,7 @@ impl Decodable for BlockHashOrNumber { } } -impl fmt::Display for BlockHashOrNumber { +impl fmt::Display for HashOrNumber { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { Self::Hash(hash) => write!(f, "{}", hash), @@ -745,7 +745,7 @@ impl fmt::Display for BlockHashOrNumber { } } -/// Error thrown when parsing a [BlockHashOrNumber] from a string. +/// Error thrown when parsing a [HashOrNumber] from a string. #[derive(Debug)] pub struct ParseBlockHashOrNumberError { input: alloc::string::String, @@ -766,7 +766,7 @@ impl fmt::Display for ParseBlockHashOrNumberError { #[cfg(feature = "std")] impl std::error::Error for ParseBlockHashOrNumberError {} -impl FromStr for BlockHashOrNumber { +impl FromStr for HashOrNumber { type Err = ParseBlockHashOrNumberError; fn from_str(s: &str) -> Result { diff --git a/crates/eips/src/lib.rs b/crates/eips/src/lib.rs index 774067e694a..2bb4b07e0cf 100644 --- a/crates/eips/src/lib.rs +++ b/crates/eips/src/lib.rs @@ -16,7 +16,8 @@ pub use eip1559::calc_next_block_base_fee; pub mod eip1898; pub use eip1898::{ - BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag, ForkBlock, NumHash, RpcBlockHash, + BlockHashOrNumber, BlockId, BlockNumHash, BlockNumberOrTag, ForkBlock, HashOrNumber, NumHash, + RpcBlockHash, }; pub mod eip2718; From e61a1843ba953871c57cd6794cbf14f599ebb13e Mon Sep 17 00:00:00 2001 From: refcell Date: Wed, 11 Sep 2024 22:36:45 -0400 Subject: [PATCH 161/186] feat(engine): no_std engine types (#1268) * feat: support no_std in alloy-rpc-types-eth * feat: derive_more error * ci: add no-std check * ci: update script * fix: crate collections * fix: fmt * chore: remove unused hash_map re-export * feat: converts engine rpc types to no-std * feat: derive_more display + std feature * fix: jwt feat * fix: clippy warnings * fix: clippy warnings * fix: error source * fix: remove tree * fix: std * fix: std * fix: std * fix: dep * fix: fmt * fix: ssz derive depends on std * fix: missing deps jwt feat * fix: raw duration * fix: fmts * touchups * fix: last nits * fix: remove core result * fix: remove manual result imports * fix: fmts --------- Co-authored-by: Matthias Seitz --- crates/rpc-types-engine/Cargo.toml | 22 ++--- crates/rpc-types-engine/src/cancun.rs | 2 + crates/rpc-types-engine/src/forkchoice.rs | 11 ++- crates/rpc-types-engine/src/identification.rs | 7 +- crates/rpc-types-engine/src/jwt.rs | 68 +++++++++++---- crates/rpc-types-engine/src/lib.rs | 20 +++-- crates/rpc-types-engine/src/payload.rs | 83 ++++++++++++------- 7 files changed, 141 insertions(+), 72 deletions(-) diff --git a/crates/rpc-types-engine/Cargo.toml b/crates/rpc-types-engine/Cargo.toml index 4d50ab3b6ff..c6bd5e41d54 100644 --- a/crates/rpc-types-engine/Cargo.toml +++ b/crates/rpc-types-engine/Cargo.toml @@ -20,32 +20,34 @@ workspace = true [dependencies] # ethereum +alloy-serde.workspace = true +alloy-rpc-types-eth.workspace = true alloy-rlp = { workspace = true, features = ["arrayvec", "derive"] } alloy-primitives = { workspace = true, features = ["rlp", "serde"] } -alloy-consensus = { workspace = true, features = ["std"] } -alloy-rpc-types-eth.workspace = true -alloy-serde.workspace = true +alloy-consensus = { workspace = true, features = ["serde"] } alloy-eips = { workspace = true, features = ["serde"] } +# misc +serde = { workspace = true, features = ["derive"] } +derive_more = { workspace = true, features = ["display"] } + # ssz ethereum_ssz_derive = { workspace = true, optional = true } ethereum_ssz = { workspace = true, optional = true } -serde = { workspace = true, features = ["derive"] } -thiserror.workspace = true - # jsonrpsee jsonrpsee-types = { version = "0.24", optional = true } # jwt -jsonwebtoken = { version = "9.3.0", optional = true } rand = { workspace = true, optional = true } +jsonwebtoken = { version = "9.3.0", optional = true } [features] -default = ["jwt"] +default = ["jwt", "std"] +std = ["alloy-rpc-types-eth/std", "alloy-consensus/std", "derive_more/std"] jwt = ["dep:jsonwebtoken", "dep:rand"] -jsonrpsee-types = ["dep:jsonrpsee-types"] -ssz = ["dep:ethereum_ssz", "dep:ethereum_ssz_derive", "alloy-eips/ssz"] +jsonrpsee-types = ["dep:jsonrpsee-types", "alloy-rpc-types-eth/jsonrpsee-types"] +ssz = ["std", "dep:ethereum_ssz", "dep:ethereum_ssz_derive", "alloy-eips/ssz"] kzg = ["alloy-consensus/kzg"] [dev-dependencies] diff --git a/crates/rpc-types-engine/src/cancun.rs b/crates/rpc-types-engine/src/cancun.rs index e1809a1a049..bdef54daa6d 100644 --- a/crates/rpc-types-engine/src/cancun.rs +++ b/crates/rpc-types-engine/src/cancun.rs @@ -1,6 +1,8 @@ //! Contains types related to the Cancun hardfork that will be used by RPC to communicate with the //! beacon consensus engine. +use alloc::vec::Vec; + use alloy_primitives::B256; /// Fields introduced in `engine_newPayloadV3` that are not present in the `ExecutionPayload` RPC diff --git a/crates/rpc-types-engine/src/forkchoice.rs b/crates/rpc-types-engine/src/forkchoice.rs index bcf0be59f3a..628e682d2cd 100644 --- a/crates/rpc-types-engine/src/forkchoice.rs +++ b/crates/rpc-types-engine/src/forkchoice.rs @@ -69,22 +69,25 @@ impl ForkchoiceState { /// /// These are considered hard RPC errors and are _not_ returned as [PayloadStatus] or /// [PayloadStatusEnum::Invalid]. -#[derive(Clone, Copy, Debug, PartialEq, Eq, thiserror::Error)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, derive_more::Display)] pub enum ForkchoiceUpdateError { /// The forkchoice update has been processed, but the requested contained invalid /// [PayloadAttributes](crate::PayloadAttributes). /// /// This is returned as an error because the payload attributes are invalid and the payload is not valid, See - #[error("invalid payload attributes")] + #[display("invalid payload attributes")] UpdatedInvalidPayloadAttributes, /// The given [ForkchoiceState] is invalid or inconsistent. - #[error("invalid forkchoice state")] + #[display("invalid forkchoice state")] InvalidState, /// Thrown when a forkchoice final block does not exist in the database. - #[error("final block not available in database")] + #[display("final block not available in database")] UnknownFinalBlock, } +#[cfg(feature = "std")] +impl std::error::Error for ForkchoiceUpdateError {} + #[cfg(feature = "jsonrpsee-types")] impl From for jsonrpsee_types::error::ErrorObject<'static> { fn from(value: ForkchoiceUpdateError) -> Self { diff --git a/crates/rpc-types-engine/src/identification.rs b/crates/rpc-types-engine/src/identification.rs index 0dcdc04ab46..bf3248b2e3d 100644 --- a/crates/rpc-types-engine/src/identification.rs +++ b/crates/rpc-types-engine/src/identification.rs @@ -1,7 +1,8 @@ //! Client identification: +use alloc::string::{String, ToString}; +use core::str::FromStr; use serde::{Deserialize, Serialize}; -use std::str::FromStr; /// 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. @@ -93,8 +94,8 @@ impl FromStr for ClientCode { } } -impl std::fmt::Display for ClientCode { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Display for ClientCode { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(f, "{}", self.as_str()) } } diff --git a/crates/rpc-types-engine/src/jwt.rs b/crates/rpc-types-engine/src/jwt.rs index 4e29de7fca9..dbc70d880f6 100644 --- a/crates/rpc-types-engine/src/jwt.rs +++ b/crates/rpc-types-engine/src/jwt.rs @@ -1,53 +1,54 @@ //! JWT (JSON Web Token) utilities for the Engine API. +use alloc::{format, string::String}; use alloy_primitives::hex; +use core::{str::FromStr, time::Duration}; 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, path::{Path, PathBuf}, - str::FromStr, - time::Duration, }; -use thiserror::Error; /// Errors returned by the [`JwtSecret`] -#[derive(Error, Debug)] +#[derive(Debug, derive_more::Display)] pub enum JwtError { /// An error encountered while decoding the hexadecimal string for the JWT secret. - #[error(transparent)] - JwtSecretHexDecodeError(#[from] hex::FromHexError), + #[display("{_0}")] + JwtSecretHexDecodeError(hex::FromHexError), /// The JWT key length provided is invalid, expecting a specific length. - #[error("JWT key is expected to have a length of {0} digits. {1} digits key provided")] + #[display("JWT key is expected to have a length of {_0} digits. {_1} digits key provided")] InvalidLength(usize, usize), /// The signature algorithm used in the JWT is not supported. Only HS256 is supported. - #[error("unsupported signature algorithm. Only HS256 is supported")] + #[display("unsupported signature algorithm. Only HS256 is supported")] UnsupportedSignatureAlgorithm, /// The provided signature in the JWT is invalid. - #[error("provided signature is invalid")] + #[display("provided signature is invalid")] InvalidSignature, /// The "iat" (issued-at) claim in the JWT is not within the allowed ±60 seconds from the /// current time. - #[error("IAT (issued-at) claim is not within ±60 seconds from the current time")] + #[display("IAT (issued-at) claim is not within ±60 seconds from the current time")] InvalidIssuanceTimestamp, /// The Authorization header is missing or invalid in the context of JWT validation. - #[error("Authorization header is missing or invalid")] + #[display("Authorization header is missing or invalid")] MissingOrInvalidAuthorizationHeader, /// An error occurred during JWT decoding. - #[error("JWT decoding error: {0}")] + #[display("JWT decoding error: {_0}")] JwtDecodingError(String), /// An error occurred while creating a directory to store the JWT. - #[error("failed to create dir {path:?}: {source}")] + #[display("failed to create dir {path:?}: {source}")] + #[cfg(feature = "std")] CreateDir { /// The source `io::Error`. source: io::Error, @@ -56,7 +57,8 @@ pub enum JwtError { }, /// An error occurred while reading the JWT from a file. - #[error("failed to read from {path:?}: {source}")] + #[display("failed to read from {path:?}: {source}")] + #[cfg(feature = "std")] Read { /// The source `io::Error`. source: io::Error, @@ -65,7 +67,8 @@ pub enum JwtError { }, /// An error occurred while writing the JWT to a file. - #[error("failed to write to {path:?}: {source}")] + #[display("failed to write to {path:?}: {source}")] + #[cfg(feature = "std")] Write { /// The source `io::Error`. source: io::Error, @@ -74,6 +77,25 @@ pub enum JwtError { }, } +impl From for JwtError { + fn from(err: hex::FromHexError) -> Self { + Self::JwtSecretHexDecodeError(err) + } +} + +#[cfg(feature = "std")] +impl std::error::Error for JwtError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + Self::JwtSecretHexDecodeError(err) => Some(err), + Self::CreateDir { source, .. } => Some(source), + Self::Read { source, .. } => Some(source), + Self::Write { source, .. } => Some(source), + _ => None, + } + } +} + /// Length of the hex-encoded 256 bit secret key. /// A 256-bit encoded string in Rust has a length of 64 digits because each digit represents 4 bits /// of data. In hexadecimal representation, each digit can have 16 possible values (0-9 and A-F), so @@ -161,6 +183,7 @@ impl JwtSecret { /// Tries to load a [`JwtSecret`] from the specified file path. /// I/O or secret validation errors might occur during read operations in the form of /// a [`JwtError`]. + #[cfg(feature = "std")] pub fn from_file(fpath: &Path) -> Result { let hex = fs::read_to_string(fpath) .map_err(|err| JwtError::Read { source: err, path: fpath.into() })?; @@ -170,6 +193,7 @@ impl JwtSecret { /// Creates a random [`JwtSecret`] and tries to store it at the specified path. I/O errors might /// occur during write operations in the form of a [`JwtError`] + #[cfg(feature = "std")] pub fn try_create_random(fpath: &Path) -> Result { if let Some(dir) = fpath.parent() { // Create parent directory @@ -234,8 +258,8 @@ impl JwtSecret { } } -impl std::fmt::Debug for JwtSecret { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Debug for JwtSecret { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_tuple("JwtSecretHash").field(&"{{}}").finish() } } @@ -253,7 +277,8 @@ mod tests { use super::*; use assert_matches::assert_matches; use jsonwebtoken::{encode, EncodingKey, Header}; - use std::time::{SystemTime, UNIX_EPOCH}; + #[cfg(feature = "std")] + use std::time::{Duration, SystemTime, UNIX_EPOCH}; use tempfile::tempdir; #[test] @@ -328,6 +353,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn validation_error_iat_out_of_window() { let secret = JwtSecret::random(); @@ -403,6 +429,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn ephemeral_secret_created() { let fpath: &Path = Path::new("secret0.hex"); assert!(fs::metadata(fpath).is_err()); @@ -412,6 +439,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn valid_secret_provided() { let fpath = Path::new("secret1.hex"); assert!(fs::metadata(fpath).is_err()); @@ -431,6 +459,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn invalid_hex_provided() { let fpath = Path::new("secret2.hex"); fs::write(fpath, "invalid hex").unwrap(); @@ -440,6 +469,7 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn provided_file_not_exists() { let fpath = Path::new("secret3.hex"); let result = JwtSecret::from_file(fpath); @@ -448,12 +478,14 @@ mod tests { } #[test] + #[cfg(feature = "std")] fn provided_file_is_a_directory() { let dir = tempdir().unwrap(); let result = JwtSecret::from_file(dir.path()); assert_matches!(result, Err(JwtError::Read {source: _,path}) if path == dir.into_path()); } + #[cfg(feature = "std")] fn to_u64(time: SystemTime) -> u64 { time.duration_since(UNIX_EPOCH).unwrap().as_secs() } diff --git a/crates/rpc-types-engine/src/lib.rs b/crates/rpc-types-engine/src/lib.rs index ef9e6fd932d..8bdaced5719 100644 --- a/crates/rpc-types-engine/src/lib.rs +++ b/crates/rpc-types-engine/src/lib.rs @@ -5,19 +5,29 @@ )] #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#![cfg_attr(not(feature = "std"), no_std)] + +extern crate alloc; mod cancun; +pub use cancun::*; + mod forkchoice; +pub use forkchoice::*; + mod identification; +pub use identification::*; + #[cfg(feature = "jwt")] mod jwt; -pub mod payload; -mod transition; +#[cfg(feature = "jwt")] +pub use jwt::*; -pub use self::{cancun::*, forkchoice::*, identification::*, payload::*, transition::*}; +pub mod payload; +pub use payload::*; -#[cfg(feature = "jwt")] -pub use self::jwt::*; +mod transition; +pub use transition::*; #[doc(inline)] pub use alloy_eips::eip6110::DepositRequest as DepositRequestV1; diff --git a/crates/rpc-types-engine/src/payload.rs b/crates/rpc-types-engine/src/payload.rs index 338bd0572df..6a99fe0bbd0 100644 --- a/crates/rpc-types-engine/src/payload.rs +++ b/crates/rpc-types-engine/src/payload.rs @@ -1,12 +1,17 @@ //! Payload types. + +use alloc::{ + string::{String, ToString}, + vec::Vec, +}; use alloy_consensus::{Blob, Bytes48}; use alloy_eips::{ eip6110::DepositRequest, eip7002::WithdrawalRequest, eip7251::ConsolidationRequest, }; use alloy_primitives::{Address, Bloom, Bytes, B256, B64, U256}; use alloy_rpc_types_eth::{transaction::BlobTransactionSidecar, Withdrawal}; +use core::iter::{FromIterator, IntoIterator}; use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer}; -use std::fmt; /// The execution payload body response that allows for `null` values. pub type ExecutionPayloadBodiesV1 = Vec>; @@ -27,8 +32,8 @@ impl PayloadId { } } -impl fmt::Display for PayloadId { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +impl core::fmt::Display for PayloadId { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { self.0.fmt(f) } } @@ -769,58 +774,58 @@ impl<'de> Deserialize<'de> for ExecutionPayload { } /// Error that can occur when handling payloads. -#[derive(Debug, thiserror::Error)] +#[derive(Debug, derive_more::Display)] pub enum PayloadError { /// Invalid payload extra data. - #[error("invalid payload extra data: {0}")] + #[display("invalid payload extra data: {_0}")] ExtraData(Bytes), /// Invalid payload base fee. - #[error("invalid payload base fee: {0}")] + #[display("invalid payload base fee: {_0}")] BaseFee(U256), /// Invalid payload blob gas used. - #[error("invalid payload blob gas used: {0}")] + #[display("invalid payload blob gas used: {_0}")] BlobGasUsed(U256), /// Invalid payload excess blob gas. - #[error("invalid payload excess blob gas: {0}")] + #[display("invalid payload excess blob gas: {_0}")] ExcessBlobGas(U256), /// withdrawals present in pre-shanghai payload. - #[error("withdrawals present in pre-shanghai payload")] + #[display("withdrawals present in pre-shanghai payload")] PreShanghaiBlockWithWitdrawals, /// withdrawals missing in post-shanghai payload. - #[error("withdrawals missing in post-shanghai payload")] + #[display("withdrawals missing in post-shanghai payload")] PostShanghaiBlockWithoutWitdrawals, /// blob transactions present in pre-cancun payload. - #[error("blob transactions present in pre-cancun payload")] + #[display("blob transactions present in pre-cancun payload")] PreCancunBlockWithBlobTransactions, /// blob gas used present in pre-cancun payload. - #[error("blob gas used present in pre-cancun payload")] + #[display("blob gas used present in pre-cancun payload")] PreCancunBlockWithBlobGasUsed, /// excess blob gas present in pre-cancun payload. - #[error("excess blob gas present in pre-cancun payload")] + #[display("excess blob gas present in pre-cancun payload")] PreCancunBlockWithExcessBlobGas, /// cancun fields present in pre-cancun payload. - #[error("cancun fields present in pre-cancun payload")] + #[display("cancun fields present in pre-cancun payload")] PreCancunWithCancunFields, /// blob transactions missing in post-cancun payload. - #[error("blob transactions missing in post-cancun payload")] + #[display("blob transactions missing in post-cancun payload")] PostCancunBlockWithoutBlobTransactions, /// blob gas used missing in post-cancun payload. - #[error("blob gas used missing in post-cancun payload")] + #[display("blob gas used missing in post-cancun payload")] PostCancunBlockWithoutBlobGasUsed, /// excess blob gas missing in post-cancun payload. - #[error("excess blob gas missing in post-cancun payload")] + #[display("excess blob gas missing in post-cancun payload")] PostCancunBlockWithoutExcessBlobGas, /// cancun fields missing in post-cancun payload. - #[error("cancun fields missing in post-cancun payload")] + #[display("cancun fields missing in post-cancun payload")] PostCancunWithoutCancunFields, /// blob transactions present in pre-prague payload. - #[error("eip 7702 transactions present in pre-prague payload")] + #[display("eip 7702 transactions present in pre-prague payload")] PrePragueBlockWithEip7702Transactions, /// requests present in pre-prague payload. - #[error("requests present in pre-prague payload")] + #[display("requests present in pre-prague payload")] PrePragueBlockRequests, /// Invalid payload block hash. - #[error("block hash mismatch: want {consensus}, got {execution}")] + #[display("block hash mismatch: want {consensus}, got {execution}")] BlockHash { /// The block hash computed from the payload. execution: B256, @@ -828,11 +833,21 @@ pub enum PayloadError { consensus: B256, }, /// Expected blob versioned hashes do not match the given transactions. - #[error("expected blob versioned hashes do not match the given transactions")] + #[display("expected blob versioned hashes do not match the given transactions")] InvalidVersionedHashes, /// Encountered decoding error. - #[error(transparent)] - Decode(#[from] alloy_rlp::Error), + #[display("{_0}")] + Decode(alloy_rlp::Error), +} + +#[cfg(feature = "std")] +impl std::error::Error for PayloadError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match self { + Self::Decode(err) => Some(err), + _ => None, + } + } } impl PayloadError { @@ -962,8 +977,8 @@ impl PayloadStatus { } } -impl fmt::Display for PayloadStatus { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +impl core::fmt::Display for PayloadStatus { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!( f, "PayloadStatus {{ status: {}, latestValidHash: {:?} }}", @@ -1054,8 +1069,8 @@ impl PayloadStatusEnum { } } -impl fmt::Display for PayloadStatusEnum { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { +impl core::fmt::Display for PayloadStatusEnum { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { match self { Self::Invalid { validation_error } => { f.write_str(self.as_str())?; @@ -1070,16 +1085,16 @@ impl fmt::Display for PayloadStatusEnum { /// Various errors that can occur when validating a payload or forkchoice update. /// /// This is intended for the [PayloadStatusEnum::Invalid] variant. -#[derive(Clone, Copy, Debug, PartialEq, Eq, thiserror::Error)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, derive_more::Display)] pub enum PayloadValidationError { /// Thrown when a forkchoice update's head links to a previously rejected payload. - #[error("links to previously rejected block")] + #[display("links to previously rejected block")] LinksToRejectedPayload, /// Thrown when a new payload contains a wrong block number. - #[error("invalid block number")] + #[display("invalid block number")] InvalidBlockNumber, /// Thrown when a new payload contains a wrong state root - #[error("invalid merkle root: (remote: {remote:?} local: {local:?})")] + #[display("invalid merkle root: (remote: {remote:?} local: {local:?})")] InvalidStateRoot { /// The state root of the payload we received from remote (CL) remote: B256, @@ -1088,9 +1103,13 @@ pub enum PayloadValidationError { }, } +#[cfg(feature = "std")] +impl std::error::Error for PayloadValidationError {} + #[cfg(test)] mod tests { use super::*; + use alloc::vec; #[test] fn serde_payload_status() { From 1d9e194b74539911f321d49fc2b3f9db71d8b85e Mon Sep 17 00:00:00 2001 From: Emilia Hane Date: Thu, 12 Sep 2024 07:30:52 +0200 Subject: [PATCH 162/186] Add trait methods `cumulative_gas_used` and `state_root` to `ReceiptResponse` (#1275) * Add trait methods cumulative_gas_used and state_root to ReceiptResponse * touchup --------- Co-authored-by: Matthias Seitz --- crates/network-primitives/src/traits.rs | 16 ++++++++++++++++ crates/rpc-types-eth/src/transaction/receipt.rs | 8 ++++++++ 2 files changed, 24 insertions(+) diff --git a/crates/network-primitives/src/traits.rs b/crates/network-primitives/src/traits.rs index 53a8ef39703..a8ec7e3f8b2 100644 --- a/crates/network-primitives/src/traits.rs +++ b/crates/network-primitives/src/traits.rs @@ -51,6 +51,14 @@ pub trait ReceiptResponse { /// EIP-7702 Authorization list. fn authorization_list(&self) -> Option<&[SignedAuthorization]>; + + /// Returns the cumulative gas used at this receipt. + fn cumulative_gas_used(&self) -> u128; + + /// The post-transaction state root (pre Byzantium) + /// + /// EIP98 makes this field optional. + fn state_root(&self) -> Option; } /// Transaction JSON-RPC response. @@ -221,6 +229,14 @@ impl ReceiptResponse for WithOtherFields { fn authorization_list(&self) -> Option<&[SignedAuthorization]> { self.inner.authorization_list() } + + fn cumulative_gas_used(&self) -> u128 { + self.inner.cumulative_gas_used() + } + + fn state_root(&self) -> Option { + self.inner.state_root() + } } impl BlockResponse for WithOtherFields { diff --git a/crates/rpc-types-eth/src/transaction/receipt.rs b/crates/rpc-types-eth/src/transaction/receipt.rs index 8714203ebc1..7fb376734e9 100644 --- a/crates/rpc-types-eth/src/transaction/receipt.rs +++ b/crates/rpc-types-eth/src/transaction/receipt.rs @@ -184,6 +184,14 @@ impl> ReceiptResponse for TransactionReceipt { fn authorization_list(&self) -> Option<&[SignedAuthorization]> { self.authorization_list.as_deref() } + + fn cumulative_gas_used(&self) -> u128 { + self.inner.cumulative_gas_used() + } + + fn state_root(&self) -> Option { + self.state_root + } } #[cfg(test)] From d535ac15c96a10641ae00a4039c47f5426fc33d3 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Thu, 12 Sep 2024 08:52:57 +0200 Subject: [PATCH 163/186] feat: add serde for NumHash (#1277) --- crates/eips/src/eip1898.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/eips/src/eip1898.rs b/crates/eips/src/eip1898.rs index 4b0690f78af..56be68bff2d 100644 --- a/crates/eips/src/eip1898.rs +++ b/crates/eips/src/eip1898.rs @@ -602,6 +602,7 @@ impl FromStr for BlockId { /// A number and a hash. #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct NumHash { /// The number pub number: u64, From 3d8c680c523f49cd9d2c00fe969f449e1c53495a Mon Sep 17 00:00:00 2001 From: zerosnacks <95942363+zerosnacks@users.noreply.github.com> Date: Thu, 12 Sep 2024 15:12:12 +0200 Subject: [PATCH 164/186] feat: improve node bindings (#1279) * add run_with_tempdir * update tests, now picks random instance by default * document new random port picking * fix clippy * add port customization * reset instance when configuring custom port as this is incompatible in reth * additional tests for http_port(0) * fix comment --- crates/node-bindings/Cargo.toml | 4 +- crates/node-bindings/src/lib.rs | 3 +- crates/node-bindings/src/node.rs | 46 ++--- crates/node-bindings/src/nodes/anvil.rs | 55 +----- crates/node-bindings/src/nodes/geth.rs | 43 ++-- crates/node-bindings/src/nodes/reth.rs | 252 ++++++++++++++++++------ crates/node-bindings/src/utils.rs | 25 +++ crates/provider/src/builder.rs | 7 +- crates/provider/src/ext/admin.rs | 56 +++--- crates/provider/src/ext/debug.rs | 76 +++---- crates/provider/src/ext/net.rs | 39 ++-- crates/provider/src/ext/txpool.rs | 50 +++-- crates/rpc-client/tests/it/ipc.rs | 34 ++-- 13 files changed, 409 insertions(+), 281 deletions(-) diff --git a/crates/node-bindings/Cargo.toml b/crates/node-bindings/Cargo.toml index bb55e3ab08f..67d34c7ffbd 100644 --- a/crates/node-bindings/Cargo.toml +++ b/crates/node-bindings/Cargo.toml @@ -22,11 +22,9 @@ workspace = true alloy-primitives = { workspace = true, features = ["std", "k256", "serde"] } alloy-genesis.workspace = true k256.workspace = true +rand.workspace = true serde_json = { workspace = true, features = ["std"] } tempfile.workspace = true thiserror.workspace = true tracing.workspace = true url.workspace = true - -[dev-dependencies] -rand.workspace = true diff --git a/crates/node-bindings/src/lib.rs b/crates/node-bindings/src/lib.rs index 6df8d1e9ff4..2ed26210609 100644 --- a/crates/node-bindings/src/lib.rs +++ b/crates/node-bindings/src/lib.rs @@ -21,8 +21,7 @@ pub use nodes::{ mod node; pub use node::*; -mod utils; -use utils::*; +pub mod utils; /// 1 Ether = 1e18 Wei == 0x0de0b6b3a7640000 Wei pub const WEI_IN_ETHER: U256 = U256::from_limbs([0x0de0b6b3a7640000, 0x0, 0x0, 0x0]); diff --git a/crates/node-bindings/src/node.rs b/crates/node-bindings/src/node.rs index b89056142d2..8a8b94fac0c 100644 --- a/crates/node-bindings/src/node.rs +++ b/crates/node-bindings/src/node.rs @@ -1,5 +1,6 @@ //! Node-related types and constants. +use alloy_primitives::hex; use std::time::Duration; use thiserror::Error; @@ -9,31 +10,9 @@ pub const NODE_STARTUP_TIMEOUT: Duration = Duration::from_secs(10); /// Timeout for waiting for the node to add a peer. pub const NODE_DIAL_LOOP_TIMEOUT: Duration = Duration::from_secs(20); -/// Errors that can occur when working with a node instance. -#[derive(Debug)] -pub enum NodeInstanceError { - /// Timed out waiting for a message from node's stderr. - Timeout(String), - - /// A line could not be read from the node's stderr. - ReadLineError(std::io::Error), - - /// The child node process's stderr was not captured. - NoStderr, - - /// The child node process's stdout was not captured. - NoStdout, -} - -/// Errors that can occur when working with the node. +/// Errors that can occur when working with the node instance. #[derive(Debug, Error)] pub enum NodeError { - /// The chain id was not set. - #[error("the chain ID was not set")] - ChainIdNotSet, - /// Could not create the data directory. - #[error("could not create directory: {0}")] - CreateDirError(std::io::Error), /// No stderr was captured from the child process. #[error("no stderr was captured from the process")] NoStderr, @@ -49,6 +28,14 @@ pub enum NodeError { /// A line could not be read from the node stderr. #[error("could not read line from node stderr: {0}")] ReadLineError(std::io::Error), + + /// The chain id was not set. + #[error("the chain ID was not set")] + ChainIdNotSet, + /// Could not create the data directory. + #[error("could not create directory: {0}")] + CreateDirError(std::io::Error), + /// Genesis error #[error("genesis error occurred: {0}")] GenesisError(String), @@ -65,4 +52,17 @@ pub enum NodeError { /// Clique private key error #[error("clique address error: {0}")] CliqueAddressError(String), + + /// The private key could not be parsed. + #[error("could not parse private key")] + ParsePrivateKeyError, + /// An error occurred while deserializing a private key. + #[error("could not deserialize private key from bytes")] + DeserializePrivateKeyError, + /// An error occurred while parsing a hex string. + #[error(transparent)] + FromHexError(#[from] hex::FromHexError), + /// No keys available this node instance. + #[error("no keys available in this node instance")] + NoKeysAvailable, } diff --git a/crates/node-bindings/src/nodes/anvil.rs b/crates/node-bindings/src/nodes/anvil.rs index 7fbdf1f4c30..95ec994b018 100644 --- a/crates/node-bindings/src/nodes/anvil.rs +++ b/crates/node-bindings/src/nodes/anvil.rs @@ -10,9 +10,10 @@ use std::{ str::FromStr, time::{Duration, Instant}, }; -use thiserror::Error; use url::Url; +use crate::NodeError; + /// How long we will wait for anvil to indicate that it is ready. const ANVIL_STARTUP_TIMEOUT_MILLIS: u64 = 10_000; @@ -89,42 +90,6 @@ impl Drop for AnvilInstance { } } -/// Errors that can occur when working with the [`Anvil`]. -#[derive(Debug, Error)] -pub enum AnvilError { - /// Spawning the anvil process failed. - #[error("could not start anvil: {0}")] - SpawnError(std::io::Error), - - /// Timed out waiting for a message from anvil's stderr. - #[error("timed out waiting for anvil to spawn; is anvil installed?")] - Timeout, - - /// A line could not be read from the geth stderr. - #[error("could not read line from anvil stderr: {0}")] - ReadLineError(std::io::Error), - - /// The child anvil process's stderr was not captured. - #[error("could not get stderr for anvil child process")] - NoStderr, - - /// The private key could not be parsed. - #[error("could not parse private key")] - ParsePrivateKeyError, - - /// An error occurred while deserializing a private key. - #[error("could not deserialize private key from bytes")] - DeserializePrivateKeyError, - - /// An error occurred while parsing a hex string. - #[error(transparent)] - FromHexError(#[from] hex::FromHexError), - - /// No keys available in anvil instance. - #[error("no keys available in anvil instance")] - NoKeysAvailable, -} - /// Builder for launching `anvil`. /// /// # Panics @@ -288,7 +253,7 @@ impl Anvil { } /// Consumes the builder and spawns `anvil`. If spawning fails, returns an error. - pub fn try_spawn(self) -> Result { + pub fn try_spawn(self) -> Result { let mut cmd = self.program.as_ref().map_or_else(|| Command::new("anvil"), Command::new); cmd.stdout(std::process::Stdio::piped()).stderr(std::process::Stdio::inherit()); let mut port = self.port.unwrap_or_default(); @@ -316,9 +281,9 @@ impl Anvil { cmd.args(self.args); - let mut child = cmd.spawn().map_err(AnvilError::SpawnError)?; + let mut child = cmd.spawn().map_err(NodeError::SpawnError)?; - let stdout = child.stdout.take().ok_or(AnvilError::NoStderr)?; + let stdout = child.stdout.take().ok_or(NodeError::NoStderr)?; let start = Instant::now(); let mut reader = BufReader::new(stdout); @@ -331,11 +296,11 @@ impl Anvil { if start + Duration::from_millis(self.timeout.unwrap_or(ANVIL_STARTUP_TIMEOUT_MILLIS)) <= Instant::now() { - return Err(AnvilError::Timeout); + return Err(NodeError::Timeout); } let mut line = String::new(); - reader.read_line(&mut line).map_err(AnvilError::ReadLineError)?; + reader.read_line(&mut line).map_err(NodeError::ReadLineError)?; trace!(target: "anvil", line); if let Some(addr) = line.strip_prefix("Listening on") { // @@ -352,10 +317,10 @@ impl Anvil { if is_private_key && line.starts_with('(') { let key_str = - line.split("0x").last().ok_or(AnvilError::ParsePrivateKeyError)?.trim(); - let key_hex = hex::decode(key_str).map_err(AnvilError::FromHexError)?; + line.split("0x").last().ok_or(NodeError::ParsePrivateKeyError)?.trim(); + let key_hex = hex::decode(key_str).map_err(NodeError::FromHexError)?; let key = K256SecretKey::from_bytes((&key_hex[..]).into()) - .map_err(|_| AnvilError::DeserializePrivateKeyError)?; + .map_err(|_| NodeError::DeserializePrivateKeyError)?; addresses.push(Address::from_public_key(SigningKey::from(&key).verifying_key())); private_keys.push(key); } diff --git a/crates/node-bindings/src/nodes/geth.rs b/crates/node-bindings/src/nodes/geth.rs index a87418928e3..fd7e200f6a0 100644 --- a/crates/node-bindings/src/nodes/geth.rs +++ b/crates/node-bindings/src/nodes/geth.rs @@ -1,8 +1,8 @@ //! Utilities for launching a Geth dev-mode instance. use crate::{ - extract_endpoint, extract_value, unused_port, NodeError, NodeInstanceError, - NODE_DIAL_LOOP_TIMEOUT, NODE_STARTUP_TIMEOUT, + utils::{extract_endpoint, extract_value, unused_port}, + NodeError, NODE_DIAL_LOOP_TIMEOUT, NODE_STARTUP_TIMEOUT, }; use alloy_genesis::{CliqueConfig, Genesis}; use alloy_primitives::Address; @@ -139,22 +139,22 @@ impl GethInstance { /// /// This leaves a `None` in its place, so calling methods that require a stderr to be present /// will fail if called after this. - pub fn stderr(&mut self) -> Result { - self.pid.stderr.take().ok_or(NodeInstanceError::NoStderr) + pub fn stderr(&mut self) -> Result { + self.pid.stderr.take().ok_or(NodeError::NoStderr) } /// Blocks until geth adds the specified peer, using 20s as the timeout. /// /// Requires the stderr to be present in the `GethInstance`. - pub fn wait_to_add_peer(&mut self, id: &str) -> Result<(), NodeInstanceError> { - let mut stderr = self.pid.stderr.as_mut().ok_or(NodeInstanceError::NoStderr)?; + pub fn wait_to_add_peer(&mut self, id: &str) -> Result<(), NodeError> { + let mut stderr = self.pid.stderr.as_mut().ok_or(NodeError::NoStderr)?; let mut err_reader = BufReader::new(&mut stderr); let mut line = String::new(); let start = Instant::now(); while start.elapsed() < NODE_DIAL_LOOP_TIMEOUT { line.clear(); - err_reader.read_line(&mut line).map_err(NodeInstanceError::ReadLineError)?; + err_reader.read_line(&mut line).map_err(NodeError::ReadLineError)?; // geth ids are truncated let truncated_id = if id.len() > 16 { &id[..16] } else { id }; @@ -162,7 +162,7 @@ impl GethInstance { return Ok(()); } } - Err(NodeInstanceError::Timeout("Timed out waiting for geth to add a peer".into())) + Err(NodeError::Timeout) } } @@ -622,33 +622,20 @@ impl Geth { // These tests should use a different datadir for each `geth` spawned. #[cfg(test)] mod tests { + use crate::utils::run_with_tempdir_sync; + use super::*; - use std::path::Path; #[test] fn port_0() { - run_with_tempdir(|_| { + run_with_tempdir_sync("geth-test-", |_| { let _geth = Geth::new().disable_discovery().port(0u16).spawn(); }); } - /// Allows running tests with a temporary directory, which is cleaned up after the function is - /// called. - /// - /// Helps with tests that spawn a helper instance, which has to be dropped before the temporary - /// directory is cleaned up. - #[track_caller] - fn run_with_tempdir(f: impl Fn(&Path)) { - let temp_dir = tempfile::tempdir().unwrap(); - let temp_dir_path = temp_dir.path(); - f(temp_dir_path); - #[cfg(not(windows))] - temp_dir.close().unwrap(); - } - #[test] fn p2p_port() { - run_with_tempdir(|temp_dir_path| { + run_with_tempdir_sync("geth-test-", |temp_dir_path| { let geth = Geth::new().disable_discovery().data_dir(temp_dir_path).spawn(); let p2p_port = geth.p2p_port(); assert!(p2p_port.is_some()); @@ -657,7 +644,7 @@ mod tests { #[test] fn explicit_p2p_port() { - run_with_tempdir(|temp_dir_path| { + run_with_tempdir_sync("geth-test-", |temp_dir_path| { // if a p2p port is explicitly set, it should be used let geth = Geth::new().p2p_port(1234).data_dir(temp_dir_path).spawn(); let p2p_port = geth.p2p_port(); @@ -667,7 +654,7 @@ mod tests { #[test] fn dev_mode() { - run_with_tempdir(|temp_dir_path| { + run_with_tempdir_sync("geth-test-", |temp_dir_path| { // dev mode should not have a p2p port, and dev should be the default let geth = Geth::new().data_dir(temp_dir_path).spawn(); let p2p_port = geth.p2p_port(); @@ -679,7 +666,7 @@ mod tests { #[ignore = "fails on geth >=1.14"] #[allow(deprecated)] fn clique_correctly_configured() { - run_with_tempdir(|temp_dir_path| { + run_with_tempdir_sync("geth-test-", |temp_dir_path| { let private_key = SigningKey::random(&mut rand::thread_rng()); let geth = Geth::new() .set_clique_private_key(private_key) diff --git a/crates/node-bindings/src/nodes/reth.rs b/crates/node-bindings/src/nodes/reth.rs index 70baa113f7f..1208924e9ac 100644 --- a/crates/node-bindings/src/nodes/reth.rs +++ b/crates/node-bindings/src/nodes/reth.rs @@ -1,7 +1,8 @@ //! Utilities for launching a Reth dev-mode instance. -use crate::{extract_endpoint, NodeError, NodeInstanceError, NODE_STARTUP_TIMEOUT}; +use crate::{utils::extract_endpoint, NodeError, NODE_STARTUP_TIMEOUT}; use alloy_genesis::Genesis; +use rand::Rng; use std::{ fs::create_dir, io::{BufRead, BufReader}, @@ -17,12 +18,25 @@ const API: &str = "eth,net,web3,txpool,trace,rpc,reth,ots,admin,debug"; /// The reth command const RETH: &str = "reth"; -/// A reth instance. Will close the instance when dropped. +/// The default HTTP port for Reth. +const DEFAULT_HTTP_PORT: u16 = 8545; + +/// The default WS port for Reth. +const DEFAULT_WS_PORT: u16 = 8546; + +/// The default auth port for Reth. +const DEFAULT_AUTH_PORT: u16 = 8551; + +/// The default P2P port for Reth. +const DEFAULT_P2P_PORT: u16 = 30303; + +/// A Reth instance. Will close the instance when dropped. /// /// Construct this using [`Reth`]. #[derive(Debug)] pub struct RethInstance { pid: Child, + instance: u16, http_port: u16, ws_port: u16, auth_port: Option, @@ -33,55 +47,60 @@ pub struct RethInstance { } impl RethInstance { - /// Returns the HTTP port of this instance + /// Returns the instance number of this instance. + pub const fn instance(&self) -> u16 { + self.instance + } + + /// Returns the HTTP port of this instance. pub const fn http_port(&self) -> u16 { self.http_port } - /// Returns the WS port of this instance + /// Returns the WS port of this instance. pub const fn ws_port(&self) -> u16 { self.ws_port } - /// Returns the auth port of this instance + /// Returns the auth port of this instance. pub const fn auth_port(&self) -> Option { self.auth_port } - /// Returns the p2p port of this instance - /// If discovery is disabled, this will be `None` + /// Returns the p2p port of this instance. + /// If discovery is disabled, this will be `None`. pub const fn p2p_port(&self) -> Option { self.p2p_port } - /// Returns the HTTP endpoint of this instance + /// Returns the HTTP endpoint of this instance. #[doc(alias = "http_endpoint")] pub fn endpoint(&self) -> String { format!("http://localhost:{}", self.http_port) } - /// Returns the Websocket endpoint of this instance + /// Returns the Websocket endpoint of this instance. pub fn ws_endpoint(&self) -> String { format!("ws://localhost:{}", self.ws_port) } - /// Returns the IPC endpoint of this instance + /// Returns the IPC endpoint of this instance. pub fn ipc_endpoint(&self) -> String { self.ipc.clone().map_or_else(|| "reth.ipc".to_string(), |ipc| ipc.display().to_string()) } - /// Returns the HTTP endpoint url of this instance + /// Returns the HTTP endpoint url of this instance. #[doc(alias = "http_endpoint_url")] pub fn endpoint_url(&self) -> Url { Url::parse(&self.endpoint()).unwrap() } - /// Returns the Websocket endpoint url of this instance + /// Returns the Websocket endpoint url of this instance. pub fn ws_endpoint_url(&self) -> Url { Url::parse(&self.ws_endpoint()).unwrap() } - /// Returns the path to this instances' data directory + /// Returns the path to this instances' data directory. pub const fn data_dir(&self) -> &Option { &self.data_dir } @@ -95,8 +114,8 @@ impl RethInstance { /// /// This leaves a `None` in its place, so calling methods that require a stdout to be present /// will fail if called after this. - pub fn stdout(&mut self) -> Result { - self.pid.stdout.take().ok_or(NodeInstanceError::NoStdout) + pub fn stdout(&mut self) -> Result { + self.pid.stdout.take().ok_or(NodeError::NoStdout) } } @@ -120,7 +139,7 @@ impl Drop for RethInstance { /// let port = 8545u16; /// let url = format!("http://localhost:{}", port).to_string(); /// -/// let reth = Reth::new().instance(0).block_time("12sec").spawn(); +/// let reth = Reth::new().instance(1).block_time("12sec").spawn(); /// /// drop(reth); // this will kill the instance /// ``` @@ -128,6 +147,10 @@ impl Drop for RethInstance { #[must_use = "This Builder struct does nothing unless it is `spawn`ed"] pub struct Reth { dev: bool, + http_port: u16, + ws_port: u16, + auth_port: u16, + p2p_port: u16, block_time: Option, instance: u16, discovery_enabled: bool, @@ -142,12 +165,18 @@ pub struct Reth { impl Reth { /// Creates an empty Reth builder. /// - /// The mnemonic is chosen randomly. - pub const fn new() -> Self { + /// The instance number is set to a random number between 1 and 200 by default to reduce the + /// odds of port conflicts. This can be changed with [`Reth::instance`]. Set to 0 to use the + /// default ports. 200 is the maximum number of instances that can be run set by Reth. + pub fn new() -> Self { Self { dev: false, + http_port: DEFAULT_HTTP_PORT, + ws_port: DEFAULT_WS_PORT, + auth_port: DEFAULT_AUTH_PORT, + p2p_port: DEFAULT_P2P_PORT, block_time: None, - instance: 0, + instance: rand::thread_rng().gen_range(1..200), discovery_enabled: true, program: None, ipc_path: None, @@ -183,13 +212,45 @@ impl Reth { self } - /// Enable `dev` mode for the reth instance. + /// Enable `dev` mode for the Reth instance. pub const fn dev(mut self) -> Self { self.dev = true; self } - /// Sets the block time for the reth instance. + /// Sets the HTTP port for the Reth instance. + /// Note: this resets the instance number to 0 to allow for custom ports. + pub const fn http_port(mut self, http_port: u16) -> Self { + self.http_port = http_port; + self.instance = 0; + self + } + + /// Sets the WS port for the Reth instance. + /// Note: this resets the instance number to 0 to allow for custom ports. + pub const fn ws_port(mut self, ws_port: u16) -> Self { + self.ws_port = ws_port; + self.instance = 0; + self + } + + /// Sets the auth port for the Reth instance. + /// Note: this resets the instance number to 0 to allow for custom ports. + pub const fn auth_port(mut self, auth_port: u16) -> Self { + self.auth_port = auth_port; + self.instance = 0; + self + } + + /// Sets the p2p port for the Reth instance. + /// Note: this resets the instance number to 0 to allow for custom ports. + pub const fn p2p_port(mut self, p2p_port: u16) -> Self { + self.p2p_port = p2p_port; + self.instance = 0; + self + } + + /// Sets the block time for the Reth instance. /// Parses strings using /// This is only used if `dev` mode is enabled. pub fn block_time(mut self, block_time: &str) -> Self { @@ -197,25 +258,26 @@ impl Reth { self } - /// Disables discovery for the reth instance. + /// Disables discovery for the Reth instance. pub const fn disable_discovery(mut self) -> Self { self.discovery_enabled = false; self } - /// Sets the chain id for the reth instance. + /// Sets the chain id for the Reth instance. pub fn chain_or_path(mut self, chain_or_path: &str) -> Self { self.chain_or_path = Some(chain_or_path.to_string()); self } - /// Enable IPC for the reth instance. + /// Enable IPC for the Reth instance. pub const fn enable_ipc(mut self) -> Self { self.ipc_enabled = true; self } - /// Sets the instance number for the reth instance. + /// Sets the instance number for the Reth instance. Set to 0 to use the default ports. + /// By default, a random number between 1 and 200 is used. pub const fn instance(mut self, instance: u16) -> Self { self.instance = instance; self @@ -233,7 +295,7 @@ impl Reth { self } - /// Sets the `genesis.json` for the reth instance. + /// Sets the `genesis.json` for the Reth instance. /// /// If this is set, reth will be initialized with `reth init` and the `--datadir` option will be /// set to the same value as `data_dir`. @@ -268,6 +330,23 @@ impl Reth { // Use Reth's `node` subcommand. cmd.arg("node"); + // Set the ports if they are not the default. + if self.http_port != DEFAULT_HTTP_PORT { + cmd.arg("--http.port").arg(self.http_port.to_string()); + } + + if self.ws_port != DEFAULT_WS_PORT { + cmd.arg("--ws.port").arg(self.ws_port.to_string()); + } + + if self.auth_port != DEFAULT_AUTH_PORT { + cmd.arg("--authrpc.port").arg(self.auth_port.to_string()); + } + + if self.p2p_port != DEFAULT_P2P_PORT { + cmd.arg("--discovery.port").arg(self.p2p_port.to_string()); + } + // If the `dev` flag is set, enable it. if self.dev { // Enable the dev mode. @@ -302,14 +381,10 @@ impl Reth { cmd.arg("--ipcpath").arg(ipc); } - // Configures the ports of the node to avoid conflicts with the defaults. This is useful for - // running multiple nodes on the same machine. - // - // Changes to the following port numbers: - // - `DISCOVERY_PORT`: default + `instance` - 1 - // - `AUTH_PORT`: default + `instance` * 100 - 100 - // - `HTTP_RPC_PORT`: default - `instance` + 1 - // - `WS_RPC_PORT`: default + `instance` * 2 - 2 + // If the instance is set, use it. + // Set the `instance` to 0 to use the default ports. + // By defining a custom `http_port`, `ws_port`, `auth_port`, or `p2p_port`, the instance + // number will be set to 0 automatically. if self.instance > 0 { cmd.arg("--instance").arg(self.instance.to_string()); } @@ -411,6 +486,7 @@ impl Reth { Ok(RethInstance { pid: child, + instance: self.instance, http_port, ws_port, p2p_port: if p2p_port != 0 { Some(p2p_port) } else { None }, @@ -426,12 +502,12 @@ impl Reth { #[cfg(test)] mod tests { use super::*; - use std::path::Path; + use crate::utils::run_with_tempdir_sync; #[test] #[cfg(not(windows))] fn can_launch_reth() { - run_with_tempdir(|temp_dir_path| { + run_with_tempdir_sync("reth-test-", |temp_dir_path| { let reth = Reth::new().data_dir(temp_dir_path).spawn(); assert_ports(&reth, false); @@ -441,7 +517,7 @@ mod tests { #[test] #[cfg(not(windows))] fn can_launch_reth_sepolia() { - run_with_tempdir(|temp_dir_path| { + run_with_tempdir_sync("reth-test-", |temp_dir_path| { let reth = Reth::new().chain_or_path("sepolia").data_dir(temp_dir_path).spawn(); assert_ports(&reth, false); @@ -451,7 +527,7 @@ mod tests { #[test] #[cfg(not(windows))] fn can_launch_reth_dev() { - run_with_tempdir(|temp_dir_path| { + run_with_tempdir_sync("reth-test-", |temp_dir_path| { let reth = Reth::new().dev().disable_discovery().data_dir(temp_dir_path).spawn(); assert_ports(&reth, true); @@ -461,7 +537,7 @@ mod tests { #[test] #[cfg(not(windows))] fn can_launch_reth_dev_custom_genesis() { - run_with_tempdir(|temp_dir_path| { + run_with_tempdir_sync("reth-test-", |temp_dir_path| { let reth = Reth::new() .dev() .disable_discovery() @@ -476,7 +552,7 @@ mod tests { #[test] #[cfg(not(windows))] fn can_launch_reth_dev_custom_blocktime() { - run_with_tempdir(|temp_dir_path| { + run_with_tempdir_sync("reth-test-", |temp_dir_path| { let reth = Reth::new() .dev() .disable_discovery() @@ -491,7 +567,7 @@ mod tests { #[test] #[cfg(not(windows))] fn can_launch_reth_p2p_instance1() { - run_with_tempdir(|temp_dir_path| { + run_with_tempdir_sync("reth-test-", |temp_dir_path| { let reth = Reth::new().instance(1).data_dir(temp_dir_path).spawn(); assert_eq!(reth.http_port(), 8545); @@ -504,7 +580,7 @@ mod tests { #[test] #[cfg(not(windows))] fn can_launch_reth_p2p_instance2() { - run_with_tempdir(|temp_dir_path| { + run_with_tempdir_sync("reth-test-", |temp_dir_path| { let reth = Reth::new().instance(2).data_dir(temp_dir_path).spawn(); assert_eq!(reth.http_port(), 8544); @@ -514,29 +590,79 @@ mod tests { }); } - /// Allows running tests with a temporary directory, which is cleaned up after the function is - /// called. - /// - /// Helps with tests that spawn a helper instance, which has to be dropped before the temporary - /// directory is cleaned up. - #[track_caller] - fn run_with_tempdir(f: impl Fn(&Path)) { - let temp_dir = tempfile::tempdir().unwrap(); - let temp_dir_path = temp_dir.path(); - f(temp_dir_path); - temp_dir.close().unwrap(); + #[test] + #[cfg(not(windows))] + fn can_launch_reth_default_ports() { + run_with_tempdir_sync("reth-test-", |temp_dir_path| { + let reth = Reth::new().instance(0).data_dir(temp_dir_path).spawn(); + + assert_eq!(reth.http_port(), 8545); + assert_eq!(reth.ws_port(), 8546); + assert_eq!(reth.auth_port(), Some(8551)); + assert_eq!(reth.p2p_port(), Some(30303)); + }); } - // Asserts that the ports are set correctly for the given reth instance. - fn assert_ports(reth: &RethInstance, dev: bool) { - assert_eq!(reth.http_port(), 8545); - assert_eq!(reth.ws_port(), 8546); - assert_eq!(reth.auth_port(), Some(8551)); + #[test] + #[cfg(not(windows))] + fn can_launch_reth_custom_port() { + run_with_tempdir_sync("reth-test-", |temp_dir_path| { + let reth = Reth::new().http_port(8577).data_dir(temp_dir_path).spawn(); + + assert_eq!(reth.http_port(), 8577); + assert_eq!(reth.ws_port(), DEFAULT_WS_PORT); + assert_eq!(reth.auth_port(), Some(DEFAULT_AUTH_PORT)); + assert_eq!(reth.p2p_port(), Some(DEFAULT_P2P_PORT)); + }); + } - if dev { - assert_eq!(reth.p2p_port(), None); - } else { - assert_eq!(reth.p2p_port(), Some(30303)); - } + #[test] + #[cfg(not(windows))] + fn can_launch_reth_custom_ports() { + run_with_tempdir_sync("reth-test-", |temp_dir_path| { + let reth = Reth::new() + .http_port(8577) + .ws_port(8578) + .auth_port(8579) + .p2p_port(30307) + .data_dir(temp_dir_path) + .spawn(); + + assert_eq!(reth.http_port(), 8577); + assert_eq!(reth.ws_port(), 8578); + assert_eq!(reth.auth_port(), Some(8579)); + assert_eq!(reth.p2p_port(), Some(30307)); + }); + } + + #[test] + #[cfg(not(windows))] + fn can_launch_reth_random_port() { + run_with_tempdir_sync("reth-test-", |temp_dir_path| { + let reth = Reth::new().http_port(0).data_dir(temp_dir_path).spawn(); + + // Assert that a random unused port is used picked by the OS. + assert_ne!(reth.http_port(), DEFAULT_HTTP_PORT); + + assert_eq!(reth.ws_port(), DEFAULT_WS_PORT); + assert_eq!(reth.auth_port(), Some(DEFAULT_AUTH_PORT)); + assert_eq!(reth.p2p_port(), Some(DEFAULT_P2P_PORT)); + }); + } + + // Asserts that the ports are set correctly for the given Reth instance. + fn assert_ports(reth: &RethInstance, dev: bool) { + // Changes to the following port numbers for each instance: + // - `HTTP_RPC_PORT`: default - `instance` + 1 + // - `WS_RPC_PORT`: default + `instance` * 2 - 2 + // - `AUTH_PORT`: default + `instance` * 100 - 100 + // - `DISCOVERY_PORT`: default + `instance` - 1 + assert_eq!(reth.http_port(), DEFAULT_HTTP_PORT - reth.instance + 1); + assert_eq!(reth.ws_port(), DEFAULT_WS_PORT + reth.instance * 2 - 2); + assert_eq!(reth.auth_port(), Some(DEFAULT_AUTH_PORT + reth.instance * 100 - 100)); + assert_eq!( + reth.p2p_port(), + if dev { None } else { Some(DEFAULT_P2P_PORT + reth.instance - 1) } + ); } } diff --git a/crates/node-bindings/src/utils.rs b/crates/node-bindings/src/utils.rs index 11c52e1e3f7..e3ee8a4511e 100644 --- a/crates/node-bindings/src/utils.rs +++ b/crates/node-bindings/src/utils.rs @@ -2,8 +2,11 @@ use std::{ borrow::Cow, + future::Future, net::{SocketAddr, TcpListener}, + path::PathBuf, }; +use tempfile::TempDir; /// A bit of hack to find an unused TCP port. /// @@ -65,6 +68,28 @@ pub(crate) fn extract_endpoint(key: &str, line: &str) -> Option { val.parse::().ok() } +/// Runs the given closure with a temporary directory. +pub fn run_with_tempdir_sync(prefix: &str, f: impl FnOnce(PathBuf)) { + let temp_dir = TempDir::with_prefix(prefix).unwrap(); + let temp_dir_path = temp_dir.path().to_path_buf(); + f(temp_dir_path); + #[cfg(not(windows))] + temp_dir.close().unwrap(); +} + +/// Runs the given async closure with a temporary directory. +pub async fn run_with_tempdir(prefix: &str, f: F) +where + F: FnOnce(PathBuf) -> Fut, + Fut: Future, +{ + let temp_dir = TempDir::with_prefix(prefix).unwrap(); + let temp_dir_path = temp_dir.path().to_path_buf(); + f(temp_dir_path).await; + #[cfg(not(windows))] + temp_dir.close().unwrap(); +} + #[test] fn test_extract_http_address() { let line = "INFO [07-01|13:20:42.774] HTTP server started endpoint=127.0.0.1:8545 auth=false prefix= cors= vhosts=localhost"; diff --git a/crates/provider/src/builder.rs b/crates/provider/src/builder.rs index 4eda6628d2f..a7e71ef9b17 100644 --- a/crates/provider/src/builder.rs +++ b/crates/provider/src/builder.rs @@ -371,7 +371,7 @@ impl ProviderBuilder { type JoinedEthereumWalletFiller = JoinFill>; #[cfg(any(test, feature = "anvil-node"))] -type AnvilProviderResult = Result; +type AnvilProviderResult = Result; // Enabled when the `anvil` feature is enabled, or when both in test and the // `reqwest` feature is enabled. @@ -490,9 +490,8 @@ impl ProviderBuilder { let url = anvil_layer.endpoint_url(); let default_keys = anvil_layer.instance().keys().to_vec(); - let (default_key, remaining_keys) = default_keys - .split_first() - .ok_or(alloy_node_bindings::anvil::AnvilError::NoKeysAvailable)?; + let (default_key, remaining_keys) = + default_keys.split_first().ok_or(alloy_node_bindings::NodeError::NoKeysAvailable)?; let default_signer = alloy_signer_local::LocalSigner::from(default_key.clone()); let mut wallet = alloy_network::EthereumWallet::from(default_signer); diff --git a/crates/provider/src/ext/admin.rs b/crates/provider/src/ext/admin.rs index c1872f8e9ec..87471c8064d 100644 --- a/crates/provider/src/ext/admin.rs +++ b/crates/provider/src/ext/admin.rs @@ -85,39 +85,43 @@ where #[cfg(test)] mod test { - use crate::ProviderBuilder; - use super::*; - use alloy_node_bindings::Geth; - use tempfile::TempDir; + use crate::ProviderBuilder; + use alloy_node_bindings::{utils::run_with_tempdir, Geth}; #[tokio::test] async fn node_info() { - let temp_dir = TempDir::with_prefix("geth-test-").unwrap(); - let geth = Geth::new().disable_discovery().data_dir(temp_dir.path()).spawn(); - let provider = ProviderBuilder::new().on_http(geth.endpoint_url()); - let node_info = provider.node_info().await.unwrap(); - assert!(node_info.enode.starts_with("enode://")); + run_with_tempdir("geth-test-", |temp_dir| async move { + let geth = Geth::new().disable_discovery().data_dir(temp_dir).spawn(); + let provider = ProviderBuilder::new().on_http(geth.endpoint_url()); + let node_info = provider.node_info().await.unwrap(); + assert!(node_info.enode.starts_with("enode://")); + }) + .await; } #[tokio::test] async fn admin_peers() { - let temp_dir = TempDir::with_prefix("geth-test-1").unwrap(); - let temp_dir_2 = TempDir::with_prefix("geth-test-2").unwrap(); - let geth1 = Geth::new().disable_discovery().data_dir(temp_dir.path()).spawn(); - let mut geth2 = - Geth::new().disable_discovery().port(0u16).data_dir(temp_dir_2.path()).spawn(); - - let provider1 = ProviderBuilder::new().on_http(geth1.endpoint_url()); - let provider2 = ProviderBuilder::new().on_http(geth2.endpoint_url()); - let node1_info = provider1.node_info().await.unwrap(); - let node1_id = node1_info.id; - let node1_enode = node1_info.enode; - - let added = provider2.add_peer(&node1_enode).await.unwrap(); - assert!(added); - geth2.wait_to_add_peer(&node1_id).unwrap(); - let peers = provider2.peers().await.unwrap(); - assert_eq!(peers[0].enode, node1_enode); + run_with_tempdir("geth-test-1", |temp_dir_1| async move { + run_with_tempdir("geth-test-2", |temp_dir_2| async move { + let geth1 = Geth::new().disable_discovery().data_dir(&temp_dir_1).spawn(); + let mut geth2 = + Geth::new().disable_discovery().port(0u16).data_dir(&temp_dir_2).spawn(); + + let provider1 = ProviderBuilder::new().on_http(geth1.endpoint_url()); + let provider2 = ProviderBuilder::new().on_http(geth2.endpoint_url()); + let node1_info = provider1.node_info().await.unwrap(); + let node1_id = node1_info.id; + let node1_enode = node1_info.enode; + + let added = provider2.add_peer(&node1_enode).await.unwrap(); + assert!(added); + geth2.wait_to_add_peer(&node1_id).unwrap(); + let peers = provider2.peers().await.unwrap(); + assert_eq!(peers[0].enode, node1_enode); + }) + .await; + }) + .await; } } diff --git a/crates/provider/src/ext/debug.rs b/crates/provider/src/ext/debug.rs index 07005ae5a20..55eabc83f32 100644 --- a/crates/provider/src/ext/debug.rs +++ b/crates/provider/src/ext/debug.rs @@ -222,7 +222,7 @@ mod test { use super::*; use alloy_network::TransactionBuilder; - use alloy_node_bindings::Geth; + use alloy_node_bindings::{utils::run_with_tempdir, Geth}; use alloy_primitives::{address, U256}; fn init_tracing() { @@ -283,50 +283,58 @@ mod test { #[tokio::test] async fn call_debug_get_raw_header() { - let temp_dir = tempfile::TempDir::with_prefix("geth-test-").unwrap(); - let geth = Geth::new().disable_discovery().data_dir(temp_dir.path()).spawn(); - let provider = ProviderBuilder::new().on_http(geth.endpoint_url()); - - let rlp_header = provider - .debug_get_raw_header(BlockId::Number(BlockNumberOrTag::Latest)) - .await - .expect("debug_getRawHeader call should succeed"); - - assert!(!rlp_header.is_empty()); + run_with_tempdir("geth-test-", |temp_dir| async move { + let geth = Geth::new().disable_discovery().data_dir(temp_dir).spawn(); + let provider = ProviderBuilder::new().on_http(geth.endpoint_url()); + + let rlp_header = provider + .debug_get_raw_header(BlockId::Number(BlockNumberOrTag::Latest)) + .await + .expect("debug_getRawHeader call should succeed"); + + assert!(!rlp_header.is_empty()); + }) + .await } #[tokio::test] async fn call_debug_get_raw_block() { - let temp_dir = tempfile::TempDir::with_prefix("geth-test-").unwrap(); - let geth = Geth::new().disable_discovery().data_dir(temp_dir.path()).spawn(); - let provider = ProviderBuilder::new().on_http(geth.endpoint_url()); - - let rlp_block = provider - .debug_get_raw_block(BlockId::Number(BlockNumberOrTag::Latest)) - .await - .expect("debug_getRawBlock call should succeed"); - - assert!(!rlp_block.is_empty()); + run_with_tempdir("geth-test-", |temp_dir| async move { + let geth = Geth::new().disable_discovery().data_dir(temp_dir).spawn(); + let provider = ProviderBuilder::new().on_http(geth.endpoint_url()); + + let rlp_block = provider + .debug_get_raw_block(BlockId::Number(BlockNumberOrTag::Latest)) + .await + .expect("debug_getRawBlock call should succeed"); + + assert!(!rlp_block.is_empty()); + }) + .await } #[tokio::test] async fn call_debug_get_raw_receipts() { - let temp_dir = tempfile::TempDir::with_prefix("geth-test-").unwrap(); - let geth = Geth::new().disable_discovery().data_dir(temp_dir.path()).spawn(); - let provider = ProviderBuilder::new().on_http(geth.endpoint_url()); - - let result = - provider.debug_get_raw_receipts(BlockId::Number(BlockNumberOrTag::Latest)).await; - assert!(result.is_ok()); + run_with_tempdir("geth-test-", |temp_dir| async move { + let geth = Geth::new().disable_discovery().data_dir(temp_dir).spawn(); + let provider = ProviderBuilder::new().on_http(geth.endpoint_url()); + + let result = + provider.debug_get_raw_receipts(BlockId::Number(BlockNumberOrTag::Latest)).await; + assert!(result.is_ok()); + }) + .await } #[tokio::test] async fn call_debug_get_bad_blocks() { - let temp_dir = tempfile::TempDir::with_prefix("geth-test-").unwrap(); - let geth = Geth::new().disable_discovery().data_dir(temp_dir.path()).spawn(); - let provider = ProviderBuilder::new().on_http(geth.endpoint_url()); - - let result = provider.debug_get_bad_blocks().await; - assert!(result.is_ok()); + run_with_tempdir("geth-test-", |temp_dir| async move { + let geth = Geth::new().disable_discovery().data_dir(temp_dir).spawn(); + let provider = ProviderBuilder::new().on_http(geth.endpoint_url()); + + let result = provider.debug_get_bad_blocks().await; + assert!(result.is_ok()); + }) + .await } } diff --git a/crates/provider/src/ext/net.rs b/crates/provider/src/ext/net.rs index f1d962629ae..633d58fd59e 100644 --- a/crates/provider/src/ext/net.rs +++ b/crates/provider/src/ext/net.rs @@ -41,35 +41,42 @@ mod test { use crate::ProviderBuilder; use super::*; - use alloy_node_bindings::Geth; + use alloy_node_bindings::{utils::run_with_tempdir, Geth}; #[tokio::test] async fn call_net_version() { - let temp_dir = tempfile::TempDir::with_prefix("geth-test-").unwrap(); - let geth = Geth::new().disable_discovery().data_dir(temp_dir.path()).spawn(); - let provider = ProviderBuilder::new().on_http(geth.endpoint_url()); + run_with_tempdir("geth-test-", |temp_dir| async move { + let geth = Geth::new().disable_discovery().data_dir(temp_dir).spawn(); + let provider = ProviderBuilder::new().on_http(geth.endpoint_url()); - let version = provider.net_version().await.expect("net_version call should succeed"); - assert_eq!(version, 1); + let version = provider.net_version().await.expect("net_version call should succeed"); + assert_eq!(version, 1); + }) + .await; } #[tokio::test] async fn call_net_peer_count() { - let temp_dir = tempfile::TempDir::with_prefix("geth-test-").unwrap(); - let geth = Geth::new().disable_discovery().data_dir(temp_dir.path()).spawn(); - let provider = ProviderBuilder::new().on_http(geth.endpoint_url()); + run_with_tempdir("geth-test-", |temp_dir| async move { + let geth = Geth::new().disable_discovery().data_dir(temp_dir).spawn(); + let provider = ProviderBuilder::new().on_http(geth.endpoint_url()); - let count = provider.net_peer_count().await.expect("net_peerCount call should succeed"); - assert_eq!(count, 0); + let count = provider.net_peer_count().await.expect("net_peerCount call should succeed"); + assert_eq!(count, 0); + }) + .await; } #[tokio::test] async fn call_net_listening() { - let temp_dir = tempfile::TempDir::with_prefix("geth-test-").unwrap(); - let geth = Geth::new().disable_discovery().data_dir(temp_dir.path()).spawn(); - let provider = ProviderBuilder::new().on_http(geth.endpoint_url()); + run_with_tempdir("geth-test-", |temp_dir| async move { + let geth = Geth::new().disable_discovery().data_dir(temp_dir).spawn(); + let provider = ProviderBuilder::new().on_http(geth.endpoint_url()); - let listening = provider.net_listening().await.expect("net_listening call should succeed"); - assert!(listening); + let listening = + provider.net_listening().await.expect("net_listening call should succeed"); + assert!(listening); + }) + .await; } } diff --git a/crates/provider/src/ext/txpool.rs b/crates/provider/src/ext/txpool.rs index 34e497c2190..5326ae5922c 100644 --- a/crates/provider/src/ext/txpool.rs +++ b/crates/provider/src/ext/txpool.rs @@ -78,41 +78,49 @@ mod tests { use crate::ProviderBuilder; use super::*; - use alloy_node_bindings::Geth; + use alloy_node_bindings::{utils::run_with_tempdir, Geth}; #[tokio::test] async fn test_txpool_content() { - let temp_dir = tempfile::TempDir::with_prefix("geth-test-").unwrap(); - let geth = Geth::new().disable_discovery().data_dir(temp_dir.path()).spawn(); - let provider = ProviderBuilder::new().on_http(geth.endpoint_url()); - let content = provider.txpool_content().await.unwrap(); - assert_eq!(content, TxpoolContent::default()); + run_with_tempdir("geth-test-", |temp_dir| async move { + let geth = Geth::new().disable_discovery().data_dir(temp_dir).spawn(); + let provider = ProviderBuilder::new().on_http(geth.endpoint_url()); + let content = provider.txpool_content().await.unwrap(); + assert_eq!(content, TxpoolContent::default()); + }) + .await; } #[tokio::test] async fn test_txpool_content_from() { - let temp_dir = tempfile::TempDir::with_prefix("geth-test-").unwrap(); - let geth = Geth::new().disable_discovery().data_dir(temp_dir.path()).spawn(); - let provider = ProviderBuilder::new().on_http(geth.endpoint_url()); - let content = provider.txpool_content_from(Address::default()).await.unwrap(); - assert_eq!(content, TxpoolContentFrom::default()); + run_with_tempdir("geth-test-", |temp_dir| async move { + let geth = Geth::new().disable_discovery().data_dir(temp_dir).spawn(); + let provider = ProviderBuilder::new().on_http(geth.endpoint_url()); + let content = provider.txpool_content_from(Address::default()).await.unwrap(); + assert_eq!(content, TxpoolContentFrom::default()); + }) + .await; } #[tokio::test] async fn test_txpool_inspect() { - let temp_dir = tempfile::TempDir::with_prefix("geth-test-").unwrap(); - let geth = Geth::new().disable_discovery().data_dir(temp_dir.path()).spawn(); - let provider = ProviderBuilder::new().on_http(geth.endpoint_url()); - let content = provider.txpool_inspect().await.unwrap(); - assert_eq!(content, TxpoolInspect::default()); + run_with_tempdir("geth-test-", |temp_dir| async move { + let geth = Geth::new().disable_discovery().data_dir(temp_dir).spawn(); + let provider = ProviderBuilder::new().on_http(geth.endpoint_url()); + let content = provider.txpool_inspect().await.unwrap(); + assert_eq!(content, TxpoolInspect::default()); + }) + .await; } #[tokio::test] async fn test_txpool_status() { - let temp_dir = tempfile::TempDir::with_prefix("geth-test-").unwrap(); - let geth = Geth::new().disable_discovery().data_dir(temp_dir.path()).spawn(); - let provider = ProviderBuilder::new().on_http(geth.endpoint_url()); - let content = provider.txpool_status().await.unwrap(); - assert_eq!(content, TxpoolStatus::default()); + run_with_tempdir("geth-test-", |temp_dir| async move { + let geth = Geth::new().disable_discovery().data_dir(temp_dir).spawn(); + let provider = ProviderBuilder::new().on_http(geth.endpoint_url()); + let content = provider.txpool_status().await.unwrap(); + assert_eq!(content, TxpoolStatus::default()); + }) + .await; } } diff --git a/crates/rpc-client/tests/it/ipc.rs b/crates/rpc-client/tests/it/ipc.rs index a34484e7ea4..30f0781adb8 100644 --- a/crates/rpc-client/tests/it/ipc.rs +++ b/crates/rpc-client/tests/it/ipc.rs @@ -1,24 +1,26 @@ -use alloy_node_bindings::Geth; +use alloy_node_bindings::{utils::run_with_tempdir, Geth}; use alloy_primitives::U64; use alloy_rpc_client::{ClientBuilder, RpcCall}; use alloy_transport_ipc::IpcConnect; #[tokio::test] -async fn it_makes_a_request() { - let temp_dir = tempfile::TempDir::with_prefix("geth-test-").unwrap(); - let geth = Geth::new() - .disable_discovery() - .ipc_path(temp_dir.path().join("alloy.ipc")) - .enable_ipc() - .block_time(1u64) - .data_dir(temp_dir.path()) - .spawn(); +async fn can_make_a_request() { + run_with_tempdir("geth-test-", |temp_dir| async move { + let geth = Geth::new() + .disable_discovery() + .ipc_path(temp_dir.join("alloy.ipc")) + .enable_ipc() + .block_time(1u64) + .data_dir(temp_dir) + .spawn(); - let connect = IpcConnect::new(geth.ipc_endpoint()); - let client = ClientBuilder::default().pubsub(connect).await.unwrap(); + let connect = IpcConnect::new(geth.ipc_endpoint()); + let client = ClientBuilder::default().pubsub(connect).await.unwrap(); - let req: RpcCall<_, _, U64> = client.request_noparams("eth_blockNumber"); - let timeout = tokio::time::timeout(std::time::Duration::from_secs(2), req); - let res = timeout.await.unwrap().unwrap(); - assert!(res.to::() <= 3); + let req: RpcCall<_, _, U64> = client.request_noparams("eth_blockNumber"); + let timeout = tokio::time::timeout(std::time::Duration::from_secs(2), req); + let res = timeout.await.unwrap().unwrap(); + assert!(res.to::() <= 3); + }) + .await; } From f50313a51e897bc687556a85ee34dbf515479398 Mon Sep 17 00:00:00 2001 From: zerosnacks <95942363+zerosnacks@users.noreply.github.com> Date: Thu, 12 Sep 2024 15:41:01 +0200 Subject: [PATCH 165/186] fix: `debug_traceCallMany` and `trace_callMany` (#1278) * apply bug fixes and add tests * use constants --- crates/node-bindings/src/nodes/reth.rs | 53 ++++----- crates/provider/src/ext/debug.rs | 66 ++++++++++-- crates/provider/src/ext/trace.rs | 144 ++++++++++++++++++++++++- crates/rpc-types-eth/src/call.rs | 1 + 4 files changed, 218 insertions(+), 46 deletions(-) diff --git a/crates/node-bindings/src/nodes/reth.rs b/crates/node-bindings/src/nodes/reth.rs index 1208924e9ac..f465f004915 100644 --- a/crates/node-bindings/src/nodes/reth.rs +++ b/crates/node-bindings/src/nodes/reth.rs @@ -566,46 +566,37 @@ mod tests { #[test] #[cfg(not(windows))] - fn can_launch_reth_p2p_instance1() { + fn can_launch_reth_p2p_instances() { run_with_tempdir_sync("reth-test-", |temp_dir_path| { - let reth = Reth::new().instance(1).data_dir(temp_dir_path).spawn(); + let reth = Reth::new().instance(100).data_dir(temp_dir_path).spawn(); - assert_eq!(reth.http_port(), 8545); - assert_eq!(reth.ws_port(), 8546); - assert_eq!(reth.auth_port(), Some(8551)); - assert_eq!(reth.p2p_port(), Some(30303)); - }); - } + assert_ports(&reth, false); - #[test] - #[cfg(not(windows))] - fn can_launch_reth_p2p_instance2() { - run_with_tempdir_sync("reth-test-", |temp_dir_path| { - let reth = Reth::new().instance(2).data_dir(temp_dir_path).spawn(); + run_with_tempdir_sync("reth-test-", |temp_dir_path| { + let reth = Reth::new().instance(101).data_dir(temp_dir_path).spawn(); - assert_eq!(reth.http_port(), 8544); - assert_eq!(reth.ws_port(), 8548); - assert_eq!(reth.auth_port(), Some(8651)); - assert_eq!(reth.p2p_port(), Some(30304)); + assert_ports(&reth, false); + }); }); } + // Tests that occupy the same port are combined so they are ran sequentially, to prevent + // flakiness. #[test] #[cfg(not(windows))] - fn can_launch_reth_default_ports() { + fn can_launch_reth_custom_ports() { + // Assert that all ports are default if no custom ports are set + // and the instance is set to 0. run_with_tempdir_sync("reth-test-", |temp_dir_path| { let reth = Reth::new().instance(0).data_dir(temp_dir_path).spawn(); - assert_eq!(reth.http_port(), 8545); - assert_eq!(reth.ws_port(), 8546); - assert_eq!(reth.auth_port(), Some(8551)); - assert_eq!(reth.p2p_port(), Some(30303)); + assert_eq!(reth.http_port(), DEFAULT_HTTP_PORT); + assert_eq!(reth.ws_port(), DEFAULT_WS_PORT); + assert_eq!(reth.auth_port(), Some(DEFAULT_AUTH_PORT)); + assert_eq!(reth.p2p_port(), Some(DEFAULT_P2P_PORT)); }); - } - #[test] - #[cfg(not(windows))] - fn can_launch_reth_custom_port() { + // Assert that only the HTTP port is set and the rest are default. run_with_tempdir_sync("reth-test-", |temp_dir_path| { let reth = Reth::new().http_port(8577).data_dir(temp_dir_path).spawn(); @@ -614,11 +605,8 @@ mod tests { assert_eq!(reth.auth_port(), Some(DEFAULT_AUTH_PORT)); assert_eq!(reth.p2p_port(), Some(DEFAULT_P2P_PORT)); }); - } - #[test] - #[cfg(not(windows))] - fn can_launch_reth_custom_ports() { + // Assert that all ports can be set. run_with_tempdir_sync("reth-test-", |temp_dir_path| { let reth = Reth::new() .http_port(8577) @@ -633,11 +621,8 @@ mod tests { assert_eq!(reth.auth_port(), Some(8579)); assert_eq!(reth.p2p_port(), Some(30307)); }); - } - #[test] - #[cfg(not(windows))] - fn can_launch_reth_random_port() { + // Assert that the HTTP port is picked by the OS and the rest are default. run_with_tempdir_sync("reth-test-", |temp_dir_path| { let reth = Reth::new().http_port(0).data_dir(temp_dir_path).spawn(); diff --git a/crates/provider/src/ext/debug.rs b/crates/provider/src/ext/debug.rs index 55eabc83f32..8ad57b7228a 100644 --- a/crates/provider/src/ext/debug.rs +++ b/crates/provider/src/ext/debug.rs @@ -2,7 +2,9 @@ use crate::Provider; use alloy_network::Network; use alloy_primitives::{hex, Bytes, TxHash, B256}; -use alloy_rpc_types_eth::{Block, BlockId, BlockNumberOrTag, TransactionRequest}; +use alloy_rpc_types_eth::{ + Block, BlockId, BlockNumberOrTag, Bundle, StateContext, TransactionRequest, +}; use alloy_rpc_types_trace::geth::{ BlockTraceResult, GethDebugTracingCallOptions, GethDebugTracingOptions, GethTrace, TraceResult, }; @@ -122,8 +124,8 @@ pub trait DebugApi: Send + Sync { /// Not all nodes support this call. async fn debug_trace_call_many( &self, - txs: Vec, - block: BlockId, + bundles: Vec, + state_context: StateContext, trace_options: GethDebugTracingCallOptions, ) -> TransportResult>; } @@ -208,11 +210,11 @@ where async fn debug_trace_call_many( &self, - txs: Vec, - block: BlockId, + bundles: Vec, + state_context: StateContext, trace_options: GethDebugTracingCallOptions, ) -> TransportResult> { - self.client().request("debug_traceCallMany", (txs, block, trace_options)).await + self.client().request("debug_traceCallMany", (bundles, state_context, trace_options)).await } } @@ -222,7 +224,7 @@ mod test { use super::*; use alloy_network::TransactionBuilder; - use alloy_node_bindings::{utils::run_with_tempdir, Geth}; + use alloy_node_bindings::{utils::run_with_tempdir, Geth, Reth}; use alloy_primitives::{address, U256}; fn init_tracing() { @@ -337,4 +339,54 @@ mod test { }) .await } + + #[tokio::test] + #[cfg(not(windows))] + async fn debug_trace_call_many() { + run_with_tempdir("reth-test-", |temp_dir| async move { + let reth = Reth::new().dev().disable_discovery().data_dir(temp_dir).spawn(); + let provider = + ProviderBuilder::new().with_recommended_fillers().on_http(reth.endpoint_url()); + + let tx1 = TransactionRequest::default() + .with_from(address!("0000000000000000000000000000000000000123")) + .with_to(address!("0000000000000000000000000000000000000456")); + + let tx2 = TransactionRequest::default() + .with_from(address!("0000000000000000000000000000000000000456")) + .with_to(address!("0000000000000000000000000000000000000789")); + + let bundles = vec![Bundle { transactions: vec![tx1, tx2], block_override: None }]; + let state_context = StateContext::default(); + let trace_options = GethDebugTracingCallOptions::default(); + let result = + provider.debug_trace_call_many(bundles, state_context, trace_options).await; + assert!(result.is_ok()); + + let traces = result.unwrap(); + assert_eq!( + serde_json::to_string_pretty(&traces).unwrap().trim(), + r#" +[ + [ + { + "failed": false, + "gas": 21000, + "returnValue": "", + "structLogs": [] + }, + { + "failed": false, + "gas": 21000, + "returnValue": "", + "structLogs": [] + } + ] +] +"# + .trim(), + ); + }) + .await + } } diff --git a/crates/provider/src/ext/trace.rs b/crates/provider/src/ext/trace.rs index b6a81dc2077..a0b748b5a9c 100644 --- a/crates/provider/src/ext/trace.rs +++ b/crates/provider/src/ext/trace.rs @@ -11,7 +11,7 @@ use alloy_rpc_types_trace::{ use alloy_transport::{Transport, TransportResult}; /// List of trace calls for use with [`TraceApi::trace_call_many`] -pub type TraceCallList<'a, N> = &'a [(::TransactionRequest, Vec)]; +pub type TraceCallList<'a, N> = &'a [(::TransactionRequest, &'a [TraceType])]; /// Trace namespace rpc interface that gives access to several non-standard RPC methods. #[cfg_attr(target_arch = "wasm32", async_trait::async_trait(?Send))] @@ -43,7 +43,7 @@ where fn trace_call_many<'a>( &self, request: TraceCallList<'a, N>, - ) -> RpcWithBlock, TraceResults>; + ) -> RpcWithBlock,), Vec>; /// Parity trace transaction. async fn trace_transaction( @@ -118,8 +118,8 @@ where fn trace_call_many<'a>( &self, request: TraceCallList<'a, N>, - ) -> RpcWithBlock, TraceResults> { - RpcWithBlock::new(self.weak_client(), "trace_callMany", request) + ) -> RpcWithBlock,), Vec> { + RpcWithBlock::new(self.weak_client(), "trace_callMany", (request,)) } async fn trace_transaction( @@ -178,6 +178,10 @@ where mod test { use crate::ProviderBuilder; use alloy_eips::BlockNumberOrTag; + use alloy_network::TransactionBuilder; + use alloy_node_bindings::{utils::run_with_tempdir, Reth}; + use alloy_primitives::address; + use alloy_rpc_types_eth::TransactionRequest; use super::*; @@ -186,10 +190,140 @@ mod test { } #[tokio::test] - async fn test_trace_block() { + async fn trace_block() { init_tracing(); let provider = ProviderBuilder::new().on_anvil(); let traces = provider.trace_block(BlockId::Number(BlockNumberOrTag::Latest)).await.unwrap(); assert_eq!(traces.len(), 0); } + + #[tokio::test] + #[cfg(not(windows))] + async fn trace_call() { + run_with_tempdir("reth-test-", |temp_dir| async move { + let reth = Reth::new().dev().disable_discovery().data_dir(temp_dir).spawn(); + let provider = ProviderBuilder::new().on_http(reth.endpoint_url()); + + let tx = TransactionRequest::default() + .with_from(address!("0000000000000000000000000000000000000123")) + .with_to(address!("0000000000000000000000000000000000000456")); + + let result = provider.trace_call(&tx, &[TraceType::Trace]).await; + assert!(result.is_ok()); + + let traces = result.unwrap(); + assert_eq!( + serde_json::to_string_pretty(&traces).unwrap().trim(), + r#" +{ + "output": "0x", + "stateDiff": null, + "trace": [ + { + "type": "call", + "action": { + "from": "0x0000000000000000000000000000000000000123", + "callType": "call", + "gas": "0x2fa9e78", + "input": "0x", + "to": "0x0000000000000000000000000000000000000456", + "value": "0x0" + }, + "result": { + "gasUsed": "0x0", + "output": "0x" + }, + "subtraces": 0, + "traceAddress": [] + } + ], + "vmTrace": null +} +"# + .trim(), + ); + }) + .await; + } + + #[tokio::test] + #[cfg(not(windows))] + async fn trace_call_many() { + run_with_tempdir("reth-test-", |temp_dir| async move { + let reth = Reth::new().dev().disable_discovery().data_dir(temp_dir).spawn(); + let provider = ProviderBuilder::new().on_http(reth.endpoint_url()); + + let tx1 = TransactionRequest::default() + .with_from(address!("0000000000000000000000000000000000000123")) + .with_to(address!("0000000000000000000000000000000000000456")); + + let tx2 = TransactionRequest::default() + .with_from(address!("0000000000000000000000000000000000000456")) + .with_to(address!("0000000000000000000000000000000000000789")); + + let result = provider + .trace_call_many(&[(tx1, &[TraceType::Trace]), (tx2, &[TraceType::Trace])]) + .await; + assert!(result.is_ok()); + + let traces = result.unwrap(); + assert_eq!( + serde_json::to_string_pretty(&traces).unwrap().trim(), + r#" +[ + { + "output": "0x", + "stateDiff": null, + "trace": [ + { + "type": "call", + "action": { + "from": "0x0000000000000000000000000000000000000123", + "callType": "call", + "gas": "0x2fa9e78", + "input": "0x", + "to": "0x0000000000000000000000000000000000000456", + "value": "0x0" + }, + "result": { + "gasUsed": "0x0", + "output": "0x" + }, + "subtraces": 0, + "traceAddress": [] + } + ], + "vmTrace": null + }, + { + "output": "0x", + "stateDiff": null, + "trace": [ + { + "type": "call", + "action": { + "from": "0x0000000000000000000000000000000000000456", + "callType": "call", + "gas": "0x2fa9e78", + "input": "0x", + "to": "0x0000000000000000000000000000000000000789", + "value": "0x0" + }, + "result": { + "gasUsed": "0x0", + "output": "0x" + }, + "subtraces": 0, + "traceAddress": [] + } + ], + "vmTrace": null + } +] +"# + .trim() + ); + }) + .await; + } } diff --git a/crates/rpc-types-eth/src/call.rs b/crates/rpc-types-eth/src/call.rs index f61775694ef..c3a5eefd54c 100644 --- a/crates/rpc-types-eth/src/call.rs +++ b/crates/rpc-types-eth/src/call.rs @@ -15,6 +15,7 @@ pub struct Bundle { /// All transactions to execute pub transactions: Vec, /// Block overrides to apply + #[serde(default, skip_serializing_if = "Option::is_none")] pub block_override: Option, } From 9362494a277134b7a98cac3b910aefd28216181a Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Thu, 12 Sep 2024 16:32:15 +0200 Subject: [PATCH 166/186] chore: remove eth rpc types dep from engine types (#1280) --- crates/rpc-types-engine/Cargo.toml | 5 ++--- crates/rpc-types-engine/src/payload.rs | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/crates/rpc-types-engine/Cargo.toml b/crates/rpc-types-engine/Cargo.toml index c6bd5e41d54..10b271d52c5 100644 --- a/crates/rpc-types-engine/Cargo.toml +++ b/crates/rpc-types-engine/Cargo.toml @@ -21,7 +21,6 @@ workspace = true [dependencies] # ethereum alloy-serde.workspace = true -alloy-rpc-types-eth.workspace = true alloy-rlp = { workspace = true, features = ["arrayvec", "derive"] } alloy-primitives = { workspace = true, features = ["rlp", "serde"] } alloy-consensus = { workspace = true, features = ["serde"] } @@ -44,9 +43,9 @@ jsonwebtoken = { version = "9.3.0", optional = true } [features] default = ["jwt", "std"] -std = ["alloy-rpc-types-eth/std", "alloy-consensus/std", "derive_more/std"] +std = ["alloy-consensus/std", "derive_more/std"] jwt = ["dep:jsonwebtoken", "dep:rand"] -jsonrpsee-types = ["dep:jsonrpsee-types", "alloy-rpc-types-eth/jsonrpsee-types"] +jsonrpsee-types = ["dep:jsonrpsee-types"] ssz = ["std", "dep:ethereum_ssz", "dep:ethereum_ssz_derive", "alloy-eips/ssz"] kzg = ["alloy-consensus/kzg"] diff --git a/crates/rpc-types-engine/src/payload.rs b/crates/rpc-types-engine/src/payload.rs index 6a99fe0bbd0..e9fc819fa3a 100644 --- a/crates/rpc-types-engine/src/payload.rs +++ b/crates/rpc-types-engine/src/payload.rs @@ -6,10 +6,10 @@ use alloc::{ }; use alloy_consensus::{Blob, Bytes48}; use alloy_eips::{ - eip6110::DepositRequest, eip7002::WithdrawalRequest, eip7251::ConsolidationRequest, + eip4844::BlobTransactionSidecar, eip4895::Withdrawal, eip6110::DepositRequest, + eip7002::WithdrawalRequest, eip7251::ConsolidationRequest, }; use alloy_primitives::{Address, Bloom, Bytes, B256, B64, U256}; -use alloy_rpc_types_eth::{transaction::BlobTransactionSidecar, Withdrawal}; use core::iter::{FromIterator, IntoIterator}; use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer}; From 8c5aff5dcb823e42b392d4847775e0110602ce8c Mon Sep 17 00:00:00 2001 From: refcell Date: Thu, 12 Sep 2024 15:44:36 -0400 Subject: [PATCH 167/186] feat(alloy-rpc-types-eth): Optional serde (#1276) * feat: optional serde * feat: optional serde * fix: tests * fix: enable serde for alloy-rpc-types-trace * fix: non-attr serde --- crates/contract/Cargo.toml | 2 +- crates/network/Cargo.toml | 2 +- crates/provider/Cargo.toml | 2 +- crates/rpc-types-eth/Cargo.toml | 16 ++- crates/rpc-types-eth/src/account.rs | 27 ++-- crates/rpc-types-eth/src/block.rs | 130 ++++++++++++------ crates/rpc-types-eth/src/call.rs | 40 +++--- crates/rpc-types-eth/src/erc4337.rs | 49 ++++--- crates/rpc-types-eth/src/fee.rs | 35 +++-- crates/rpc-types-eth/src/filter.rs | 87 +++++++----- crates/rpc-types-eth/src/index.rs | 30 ++-- crates/rpc-types-eth/src/log.rs | 26 ++-- crates/rpc-types-eth/src/pubsub.rs | 45 +++--- crates/rpc-types-eth/src/simulate.rs | 45 +++--- crates/rpc-types-eth/src/state.rs | 56 +++++--- crates/rpc-types-eth/src/syncing.rs | 64 +++++---- crates/rpc-types-eth/src/transaction/mod.rs | 87 +++++++++--- .../rpc-types-eth/src/transaction/receipt.rs | 47 +++++-- .../rpc-types-eth/src/transaction/request.rs | 115 ++++++++++++---- .../src/transaction/signature.rs | 28 +++- crates/rpc-types-eth/src/work.rs | 19 ++- crates/rpc-types-trace/Cargo.toml | 2 +- crates/signer-trezor/Cargo.toml | 2 +- 23 files changed, 622 insertions(+), 334 deletions(-) diff --git a/crates/contract/Cargo.toml b/crates/contract/Cargo.toml index b1862a2b99e..4456055d5b2 100644 --- a/crates/contract/Cargo.toml +++ b/crates/contract/Cargo.toml @@ -22,7 +22,7 @@ workspace = true alloy-network.workspace = true alloy-network-primitives.workspace = true alloy-provider.workspace = true -alloy-rpc-types-eth.workspace = true +alloy-rpc-types-eth = { workspace = true, features = ["serde"] } alloy-transport.workspace = true alloy-dyn-abi = { workspace = true, features = ["std"] } diff --git a/crates/network/Cargo.toml b/crates/network/Cargo.toml index 9eda78c2426..8a647bef2e5 100644 --- a/crates/network/Cargo.toml +++ b/crates/network/Cargo.toml @@ -24,7 +24,7 @@ alloy-eips = { workspace = true, features = ["serde"] } alloy-json-rpc.workspace = true alloy-network-primitives.workspace = true alloy-primitives.workspace = true -alloy-rpc-types-eth.workspace = true +alloy-rpc-types-eth = { workspace = true, features = ["std", "serde"] } alloy-signer.workspace = true alloy-serde.workspace = true alloy-sol-types.workspace = true diff --git a/crates/provider/Cargo.toml b/crates/provider/Cargo.toml index 164c442100f..e7a3b4c106a 100644 --- a/crates/provider/Cargo.toml +++ b/crates/provider/Cargo.toml @@ -29,7 +29,7 @@ alloy-signer-local = { workspace = true, optional = true } alloy-rpc-client.workspace = true alloy-rpc-types-admin = { workspace = true, optional = true } alloy-rpc-types-anvil = { workspace = true, optional = true } -alloy-rpc-types-eth.workspace = 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 } diff --git a/crates/rpc-types-eth/Cargo.toml b/crates/rpc-types-eth/Cargo.toml index dde377f60c2..14ac0ee0b2b 100644 --- a/crates/rpc-types-eth/Cargo.toml +++ b/crates/rpc-types-eth/Cargo.toml @@ -19,18 +19,19 @@ rustdoc-args = ["--cfg", "docsrs"] workspace = true [dependencies] +alloy-eips.workspace = true alloy-serde.workspace = true +alloy-consensus.workspace = true alloy-network-primitives.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"] } +alloy-primitives = { workspace = true, features = ["rlp"] } +itertools.workspace = true derive_more = { workspace = true, features = ["display"] } -itertools.workspace = true -serde = { workspace = true, features = ["derive"] } -serde_json.workspace = true +# serde +serde = { workspace = true, features = ["derive"], optional = true } +serde_json = { workspace = true, optional = true } # `no_std` compatibility cfg-if.workspace = true @@ -59,8 +60,9 @@ similar-asserts.workspace = true assert_matches.workspace = true [features] -default = ["std"] +default = ["std", "serde"] std = ["alloy-primitives/std", "alloy-consensus/std", "alloy-eips/std"] +serde = ["dep:serde", "dep:serde_json", "alloy-primitives/serde", "alloy-consensus/serde", "alloy-eips/serde"] arbitrary = [ "std", "dep:arbitrary", diff --git a/crates/rpc-types-eth/src/account.rs b/crates/rpc-types-eth/src/account.rs index 26544f6a0ab..6e99bceceba 100644 --- a/crates/rpc-types-eth/src/account.rs +++ b/crates/rpc-types-eth/src/account.rs @@ -1,6 +1,5 @@ use alloy_primitives::{Address, Bytes, B256, B512, U256}; use alloy_serde::storage::JsonStorageKey; -use serde::{Deserialize, Serialize}; use alloc::{string::String, vec::Vec}; @@ -8,15 +7,17 @@ use alloc::{string::String, vec::Vec}; pub use alloy_consensus::Account; /// Account information. -#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct AccountInfo { /// Account name pub name: String, } /// Data structure with proof for one single storage-entry -#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Clone, Debug, Default, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct EIP1186StorageProof { /// Storage key. pub key: JsonStorageKey, @@ -27,8 +28,9 @@ pub struct EIP1186StorageProof { } /// Response for EIP-1186 account proof `eth_getProof` -#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Clone, Debug, Default, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct EIP1186AccountProofResponse { /// The account address. pub address: Address, @@ -37,7 +39,7 @@ pub struct EIP1186AccountProofResponse { /// The hash of the code of the account. pub code_hash: B256, /// The account nonce. - #[serde(with = "alloy_serde::quantity")] + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))] pub nonce: u64, /// The hash of the storage of the account. pub storage_hash: B256, @@ -48,22 +50,24 @@ pub struct EIP1186AccountProofResponse { } /// Extended account information (used by `parity_allAccountInfo`). -#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct ExtAccountInfo { /// Account name pub name: String, /// Account meta JSON pub meta: String, /// Account UUID (`None` for address book entries) - #[serde(skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] pub uuid: Option, } /// account derived from a signature /// as well as information that tells if it is valid for /// the current chain -#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct RecoveredAccount { /// address of the recovered account pub address: Address, @@ -76,6 +80,7 @@ pub struct RecoveredAccount { } #[test] +#[cfg(feature = "serde")] fn test_eip_1186_account_without_storage_proof() { let response = r#"{ "address":"0xc36442b4a4522e871399cd717abdd847ab11fe88", diff --git a/crates/rpc-types-eth/src/block.rs b/crates/rpc-types-eth/src/block.rs index 82aeebe3691..83f9790e6d9 100644 --- a/crates/rpc-types-eth/src/block.rs +++ b/crates/rpc-types-eth/src/block.rs @@ -7,7 +7,6 @@ use alloy_network_primitives::{ }; use alloy_primitives::{Address, BlockHash, Bloom, Bytes, B256, B64, U256}; use alloy_serde::WithOtherFields; -use serde::{Deserialize, Serialize}; use alloc::vec::Vec; @@ -17,27 +16,31 @@ pub use alloy_eips::{ }; /// Block representation -#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Clone, Debug, Default, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct Block { /// Header of the block. - #[serde(flatten)] + #[cfg_attr(feature = "serde", serde(flatten))] pub header: H, /// Uncles' hashes. - #[serde(default)] + #[cfg_attr(feature = "serde", serde(default))] pub uncles: Vec, /// Block Transactions. In the case of an uncle block, this field is not included in RPC /// responses, and when deserialized, it will be set to [BlockTransactions::Uncle]. - #[serde( - default = "BlockTransactions::uncle", - skip_serializing_if = "BlockTransactions::is_uncle" + #[cfg_attr( + feature = "serde", + serde( + default = "BlockTransactions::uncle", + skip_serializing_if = "BlockTransactions::is_uncle" + ) )] pub transactions: BlockTransactions, /// Integer the size of this block in bytes. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub size: Option, /// Withdrawals in the block. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub withdrawals: Option>, } @@ -50,15 +53,16 @@ impl Block { /// Block header representation. #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] -#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct Header { /// Hash of the block pub hash: BlockHash, /// Hash of the parent pub parent_hash: B256, /// Hash of the uncles - #[serde(rename = "sha3Uncles")] + #[cfg_attr(feature = "serde", serde(rename = "sha3Uncles"))] pub uncles_hash: B256, /// Alias of `author` pub miner: Address, @@ -73,19 +77,19 @@ pub struct Header { /// Difficulty pub difficulty: U256, /// Block number - #[serde(with = "alloy_serde::quantity")] + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))] pub number: u64, /// Gas Limit - #[serde(default, with = "alloy_serde::quantity")] + #[cfg_attr(feature = "serde", serde(default, with = "alloy_serde::quantity"))] pub gas_limit: u128, /// Gas Used - #[serde(default, with = "alloy_serde::quantity")] + #[cfg_attr(feature = "serde", serde(default, with = "alloy_serde::quantity"))] pub gas_used: u128, /// Timestamp - #[serde(default, with = "alloy_serde::quantity")] + #[cfg_attr(feature = "serde", serde(default, with = "alloy_serde::quantity"))] pub timestamp: u64, /// Total difficulty - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub total_difficulty: Option, /// Extra data pub extra_data: Bytes, @@ -100,28 +104,49 @@ pub struct Header { /// /// See also /// And - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub mix_hash: Option, /// Nonce - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub nonce: Option, /// Base fee per unit of gas (if past London) - #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] + #[cfg_attr( + feature = "serde", + serde( + default, + skip_serializing_if = "Option::is_none", + with = "alloy_serde::quantity::opt" + ) + )] pub base_fee_per_gas: Option, /// Withdrawals root hash added by EIP-4895 and is ignored in legacy headers. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub withdrawals_root: Option, /// Blob gas used - #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] + #[cfg_attr( + feature = "serde", + serde( + default, + skip_serializing_if = "Option::is_none", + with = "alloy_serde::quantity::opt" + ) + )] pub blob_gas_used: Option, /// Excess blob gas - #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] + #[cfg_attr( + feature = "serde", + serde( + default, + skip_serializing_if = "Option::is_none", + with = "alloy_serde::quantity::opt" + ) + )] pub excess_blob_gas: Option, /// EIP-4788 parent beacon block root - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub parent_beacon_block_root: Option, /// EIP-7685 requests root. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub requests_root: Option, } @@ -282,43 +307,57 @@ impl From
for WithOtherFields
{ } /// BlockOverrides is a set of header fields to override. -#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] -#[serde(default, rename_all = "camelCase", deny_unknown_fields)] +#[derive(Clone, Debug, Default, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(default, rename_all = "camelCase", deny_unknown_fields))] pub struct BlockOverrides { /// Overrides the block number. /// /// For `eth_callMany` this will be the block number of the first simulated block. Each /// following block increments its block number by 1 // Note: geth uses `number`, erigon uses `blockNumber` - #[serde(default, skip_serializing_if = "Option::is_none", alias = "blockNumber")] + #[cfg_attr( + feature = "serde", + serde(default, skip_serializing_if = "Option::is_none", alias = "blockNumber") + )] pub number: Option, /// Overrides the difficulty of the block. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub difficulty: Option, /// Overrides the timestamp of the block. // Note: geth uses `time`, erigon uses `timestamp` - #[serde( - default, - skip_serializing_if = "Option::is_none", - alias = "timestamp", - with = "alloy_serde::quantity::opt" + #[cfg_attr( + feature = "serde", + serde( + default, + skip_serializing_if = "Option::is_none", + alias = "timestamp", + with = "alloy_serde::quantity::opt" + ) )] pub time: Option, /// Overrides the gas limit of the block. - #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] + #[cfg_attr( + feature = "serde", + serde( + default, + skip_serializing_if = "Option::is_none", + with = "alloy_serde::quantity::opt" + ) + )] pub gas_limit: Option, /// Overrides the coinbase address of the block. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub coinbase: Option
, /// Overrides the prevrandao of the block. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub random: Option, /// Overrides the basefee of the block. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub base_fee: Option, /// A dictionary that maps blockNumber to a user-defined hash. It could be queried from the /// solidity opcode BLOCKHASH. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub block_hash: Option>, } @@ -355,7 +394,7 @@ mod tests { } #[test] - #[cfg(feature = "jsonrpsee-types")] + #[cfg(all(feature = "jsonrpsee-types", feature = "serde"))] fn serde_json_header() { use jsonrpsee_types::SubscriptionResponse; let resp = r#"{"jsonrpc":"2.0","method":"eth_subscribe","params":{"subscription":"0x7eef37ff35d471f8825b1c8f67a5d3c0","result":{"hash":"0x7a7ada12e140961a32395059597764416499f4178daf1917193fad7bd2cc6386","parentHash":"0xdedbd831f496e705e7f2ec3c8dcb79051040a360bf1455dbd7eb8ea6ad03b751","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","miner":"0x0000000000000000000000000000000000000000","stateRoot":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","number":"0x8","gasUsed":"0x0","gasLimit":"0x1c9c380","extraData":"0x","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","timestamp":"0x642aa48f","difficulty":"0x0","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0000000000000000"}}}"#; @@ -366,6 +405,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn serde_block() { let block = Block { header: Header { @@ -408,6 +448,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn serde_uncle_block() { let block = Block { header: Header { @@ -450,6 +491,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn serde_block_with_withdrawals_set_as_none() { let block = Block { header: Header { @@ -492,12 +534,14 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn block_overrides() { let s = r#"{"blockNumber": "0xe39dd0"}"#; let _overrides = serde_json::from_str::(s).unwrap(); } #[test] + #[cfg(feature = "serde")] fn serde_rich_block() { let s = r#"{ "hash": "0xb25d0e54ca0104e3ebfb5a1dcdf9528140854d609886a300946fd6750dcb19f4", @@ -531,6 +575,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn serde_missing_uncles_block() { let s = r#"{ "baseFeePerGas":"0x886b221ad", @@ -572,6 +617,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn serde_block_containing_uncles() { let s = r#"{ "baseFeePerGas":"0x886b221ad", @@ -615,6 +661,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn serde_empty_block() { let s = r#"{ "hash": "0xb25d0e54ca0104e3ebfb5a1dcdf9528140854d609886a300946fd6750dcb19f4", @@ -645,6 +692,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn recompute_block_hash() { let s = r#"{ "hash": "0xb25d0e54ca0104e3ebfb5a1dcdf9528140854d609886a300946fd6750dcb19f4", diff --git a/crates/rpc-types-eth/src/call.rs b/crates/rpc-types-eth/src/call.rs index c3a5eefd54c..1020894da57 100644 --- a/crates/rpc-types-eth/src/call.rs +++ b/crates/rpc-types-eth/src/call.rs @@ -1,6 +1,5 @@ use crate::{request::TransactionRequest, BlockId, BlockOverrides}; use alloy_primitives::Bytes; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; use alloc::{ format, @@ -9,13 +8,14 @@ use alloc::{ }; /// Bundle of transactions -#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] -#[serde(default, rename_all = "camelCase")] +#[derive(Clone, Debug, Default, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct Bundle { /// All transactions to execute pub transactions: Vec, /// Block overrides to apply - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub block_override: Option, } @@ -27,27 +27,29 @@ impl From> for Bundle { } /// State context for callMany -#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] -#[serde(default, 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 StateContext { /// Block Number - #[serde(skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] pub block_number: Option, /// Inclusive number of tx to replay in block. -1 means replay all - #[serde(skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] #[doc(alias = "tx_index")] pub transaction_index: Option, } /// CallResponse for eth_callMany -#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] -#[serde(default, rename_all = "camelCase")] +#[derive(Clone, Debug, Default, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct EthCallResponse { /// eth_call output (if no error) - #[serde(skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] pub value: Option, /// eth_call output (if error) - #[serde(skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] pub error: Option, } @@ -97,10 +99,11 @@ impl From for TransactionIndex { } } -impl Serialize for TransactionIndex { +#[cfg(feature = "serde")] +impl serde::Serialize for TransactionIndex { fn serialize(&self, serializer: S) -> Result where - S: Serializer, + S: serde::Serializer, { match self { Self::All => serializer.serialize_i8(-1), @@ -109,10 +112,11 @@ impl Serialize for TransactionIndex { } } -impl<'de> Deserialize<'de> for TransactionIndex { +#[cfg(feature = "serde")] +impl<'de> serde::Deserialize<'de> for TransactionIndex { fn deserialize(deserializer: D) -> Result where - D: Deserializer<'de>, + D: serde::Deserializer<'de>, { match isize::deserialize(deserializer)? { -1 => Ok(Self::All), @@ -131,6 +135,7 @@ mod tests { use crate::BlockNumberOrTag; #[test] + #[cfg(feature = "serde")] fn transaction_index() { let s = "-1"; let idx = serde_json::from_str::(s).unwrap(); @@ -146,6 +151,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn serde_state_context() { let s = r#"{"blockNumber":"pending"}"#; let state_context = serde_json::from_str::(s).unwrap(); @@ -155,6 +161,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn serde_bundle() { let s = r#"{"transactions":[{"data":"0x70a08231000000000000000000000000000000dbc80bf780c6dc0ca16ed071b1f00cc000","to":"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"}],"blockOverride":{"timestamp":1711546233}}"#; let bundle = serde_json::from_str::(s).unwrap(); @@ -163,6 +170,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn full_bundle() { // let s = r#"{"transactions":[{"from":"0x0000000000000011110000000000000000000000","to":"0x1100000000000000000000000000000000000000","value":"0x1111111","maxFeePerGas":"0x3a35294400","maxPriorityFeePerGas":"0x3b9aca00"}]}"#; diff --git a/crates/rpc-types-eth/src/erc4337.rs b/crates/rpc-types-eth/src/erc4337.rs index cf73d8d45bf..73529dc943e 100644 --- a/crates/rpc-types-eth/src/erc4337.rs +++ b/crates/rpc-types-eth/src/erc4337.rs @@ -1,40 +1,41 @@ use crate::{collections::HashMap, Log, TransactionReceipt}; use alloy_primitives::{Address, BlockNumber, Bytes, B256, U256}; -use serde::{Deserialize, Serialize}; use alloc::vec::Vec; /// Options for conditional raw transaction submissions. // reference for the implementation // See also -#[derive(Debug, Serialize, Deserialize, Clone, Default)] -#[serde(rename_all = "camelCase")] +#[derive(Debug, Clone, Default)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct ConditionalOptions { /// A map of account addresses to their expected storage states. /// Each account can have a specified storage root or explicit slot-value pairs. - #[serde(default)] + #[cfg_attr(feature = "serde", serde(default))] pub known_accounts: HashMap, /// The minimal block number at which the transaction can be included. /// `None` indicates no minimum block number constraint. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub block_number_min: Option, /// The maximal block number at which the transaction can be included. /// `None` indicates no maximum block number constraint. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub block_number_max: Option, /// The minimal timestamp at which the transaction can be included. /// `None` indicates no minimum timestamp constraint. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub timestamp_min: Option, /// The maximal timestamp at which the transaction can be included. /// `None` indicates no maximum timestamp constraint. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub timestamp_max: Option, } /// Represents the expected state of an account for a transaction to be conditionally accepted. -#[derive(Debug, Serialize, Deserialize, Clone)] -#[serde(untagged)] +#[derive(Debug, Clone)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(untagged))] pub enum AccountStorage { /// Expected storage root hash of the account. RootHash(B256), @@ -43,8 +44,9 @@ pub enum AccountStorage { } /// [`UserOperation`] in the spec: Entry Point V0.6 -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct UserOperation { /// The address of the smart contract account pub sender: Address, @@ -72,8 +74,9 @@ pub struct UserOperation { } /// [`PackedUserOperation`] in the spec: Entry Point V0.7 -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct PackedUserOperation { /// The account making the operation. pub sender: Address, @@ -113,7 +116,8 @@ pub struct PackedUserOperation { } /// Send User Operation -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub enum SendUserOperation { /// User Operation EntryPointV06(UserOperation), @@ -122,16 +126,18 @@ pub enum SendUserOperation { } /// Response to sending a user operation. -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct SendUserOperationResponse { /// The hash of the user operation. pub user_op_hash: Bytes, } /// Represents the receipt of a user operation. -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct UserOperationReceipt { /// The hash of the user operation. pub user_op_hash: Bytes, @@ -158,8 +164,9 @@ pub struct UserOperationReceipt { } /// Represents the gas estimation for a user operation. -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct UserOperationGasEstimation { /// The gas limit for the pre-verification. pub pre_verification_gas: U256, diff --git a/crates/rpc-types-eth/src/fee.rs b/crates/rpc-types-eth/src/fee.rs index 946cfb46605..d6222da37f6 100644 --- a/crates/rpc-types-eth/src/fee.rs +++ b/crates/rpc-types-eth/src/fee.rs @@ -1,5 +1,3 @@ -use serde::{Deserialize, Serialize}; - use alloc::vec::Vec; /// Internal struct to calculate reward percentiles @@ -28,8 +26,9 @@ impl Ord for TxGasAndReward { } /// Response type for `eth_feeHistory` -#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Clone, Debug, Default, PartialEq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct FeeHistory { /// An array of block base fees per gas. /// This includes the next block after the newest of the returned range, @@ -39,7 +38,10 @@ pub struct FeeHistory { /// # Note /// /// Empty list is skipped only for compatibility with Erigon and Geth. - #[serde(default, skip_serializing_if = "Vec::is_empty", with = "alloy_serde::quantity::vec")] + #[cfg_attr( + feature = "serde", + serde(default, skip_serializing_if = "Vec::is_empty", with = "alloy_serde::quantity::vec") + )] pub base_fee_per_gas: Vec, /// An array of block gas used ratios. These are calculated as the ratio /// of `gasUsed` and `gasLimit`. @@ -47,21 +49,27 @@ pub struct FeeHistory { /// An array of block base fees per blob gas. This includes the next block after the newest /// of the returned range, because this value can be derived from the newest block. Zeroes /// are returned for pre-EIP-4844 blocks. - #[serde(default, skip_serializing_if = "Vec::is_empty", with = "alloy_serde::quantity::vec")] + #[cfg_attr( + feature = "serde", + serde(default, skip_serializing_if = "Vec::is_empty", with = "alloy_serde::quantity::vec") + )] pub base_fee_per_blob_gas: Vec, /// An array of block blob gas used ratios. These are calculated as the ratio of gasUsed and /// gasLimit. - #[serde(default, skip_serializing_if = "Vec::is_empty")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Vec::is_empty"))] pub blob_gas_used_ratio: Vec, /// Lowest number block of the returned range. - #[serde(default, with = "alloy_serde::quantity")] + #[cfg_attr(feature = "serde", serde(default, with = "alloy_serde::quantity"))] pub oldest_block: u64, /// An (optional) array of effective priority fee per gas data points from a single /// block. All zeroes are returned if the block is empty. - #[serde( - default, - skip_serializing_if = "Option::is_none", - with = "alloy_serde::u128_vec_vec_opt_via_ruint" + #[cfg_attr( + feature = "serde", + serde( + default, + skip_serializing_if = "Option::is_none", + with = "alloy_serde::u128_vec_vec_opt_via_ruint" + ) )] pub reward: Option>>, } @@ -110,6 +118,7 @@ mod tests { use similar_asserts::assert_eq; #[test] + #[cfg(feature = "serde")] fn test_fee_history_serde() { let sample = r#"{"baseFeePerGas":["0x342770c0","0x2da282a8"],"gasUsedRatio":[0.0],"baseFeePerBlobGas":["0x0","0x0"],"blobGasUsedRatio":[0.0],"oldestBlock":"0x1"}"#; let fee_history: FeeHistory = serde_json::from_str(sample).unwrap(); @@ -127,12 +136,14 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn test_fee_history_serde_2() { let json = r#"{"baseFeePerBlobGas":["0xc0","0xb2","0xab","0x98","0x9e","0x92","0xa4","0xb9","0xd0","0xea","0xfd"],"baseFeePerGas":["0x4cb8cf181","0x53075988e","0x4fb92ee18","0x45c209055","0x4e790dca2","0x58462e84e","0x5b7659f4e","0x5d66ea3aa","0x6283c6e45","0x5ecf0e1e5","0x5da59cf89"],"blobGasUsedRatio":[0.16666666666666666,0.3333333333333333,0,0.6666666666666666,0.16666666666666666,1,1,1,1,0.8333333333333334],"gasUsedRatio":[0.8288135,0.3407616666666667,0,0.9997232,0.999601,0.6444664333333333,0.5848306333333333,0.7189564,0.34952733333333336,0.4509799666666667],"oldestBlock":"0x59f94f","reward":[["0x59682f00"],["0x59682f00"],["0x0"],["0x59682f00"],["0x59682f00"],["0x3b9aca00"],["0x59682f00"],["0x59682f00"],["0x3b9aca00"],["0x59682f00"]]}"#; let _actual = serde_json::from_str::(json).unwrap(); } #[test] + #[cfg(feature = "serde")] fn test_fee_history_serde_3() { let json = r#"{"oldestBlock":"0xdee807","baseFeePerGas":["0x4ccf46253","0x4457de658","0x4531c5aee","0x3cfa33972","0x3d33403eb","0x399457884","0x40bdf9772","0x48d55e7c4","0x51e9ebf14","0x55f460bf9","0x4e31607e4"],"gasUsedRatio":[0.05909575012589385,0.5498182666666667,0.0249864,0.5146185,0.2633512,0.997582061117319,0.999914966153302,0.9986873805040722,0.6973219148223686,0.13879896448917434],"baseFeePerBlobGas":["0x0","0x0","0x0","0x0","0x0","0x0","0x0","0x0","0x0","0x0","0x0"],"blobGasUsedRatio":[0,0,0,0,0,0,0,0,0,0]}"#; let _actual = serde_json::from_str::(json).unwrap(); diff --git a/crates/rpc-types-eth/src/filter.rs b/crates/rpc-types-eth/src/filter.rs index 517259a355c..f8e5706f4c3 100644 --- a/crates/rpc-types-eth/src/filter.rs +++ b/crates/rpc-types-eth/src/filter.rs @@ -1,13 +1,7 @@ use crate::{BlockNumberOrTag, Log as RpcLog, Transaction}; +use alloc::{format, string::String, vec::Vec}; use alloy_primitives::{keccak256, Address, BlockHash, Bloom, BloomInput, B256, U256, U64}; use itertools::{EitherOrBoth::*, Itertools}; -use serde::{ - de::{DeserializeOwned, MapAccess, Visitor}, - ser::SerializeStruct, - Deserialize, Deserializer, Serialize, Serializer, -}; - -use alloc::{format, string::String, vec::Vec}; use crate::collections::{ hash_set::{IntoIter, Iter}, @@ -38,7 +32,8 @@ impl BloomFilter { } } -#[derive(Clone, Debug, Default, PartialEq, Eq, Deserialize)] +#[derive(Clone, Debug, Default, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Deserialize))] /// FilterSet is a set of values that will be used to filter logs pub struct FilterSet(HashSet); @@ -547,11 +542,14 @@ impl Filter { } } -impl Serialize for Filter { +#[cfg(feature = "serde")] +impl serde::Serialize for Filter { fn serialize(&self, serializer: S) -> Result where - S: Serializer, + S: serde::Serializer, { + use serde::ser::SerializeStruct; + let mut s = serializer.serialize_struct("Filter", 5)?; match self.block_option { FilterBlockOption::Range { from_block, to_block } => { @@ -589,14 +587,15 @@ impl Serialize for Filter { type RawAddressFilter = ValueOrArray>; type RawTopicsFilter = Vec>>>; -impl<'de> Deserialize<'de> for Filter { +#[cfg(feature = "serde")] +impl<'de> serde::Deserialize<'de> for Filter { fn deserialize(deserializer: D) -> Result where - D: Deserializer<'de>, + D: serde::Deserializer<'de>, { struct FilterVisitor; - impl<'de> Visitor<'de> for FilterVisitor { + impl<'de> serde::de::Visitor<'de> for FilterVisitor { type Value = Filter; fn expecting(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { @@ -605,7 +604,7 @@ impl<'de> Deserialize<'de> for Filter { fn visit_map(self, mut map: A) -> Result where - A: MapAccess<'de>, + A: serde::de::MapAccess<'de>, { let mut from_block: Option> = None; let mut to_block: Option> = None; @@ -760,13 +759,14 @@ impl From> for ValueOrArray { } } -impl Serialize for ValueOrArray +#[cfg(feature = "serde")] +impl serde::Serialize for ValueOrArray where - T: Serialize, + T: serde::Serialize, { fn serialize(&self, serializer: S) -> Result where - S: Serializer, + S: serde::Serializer, { match self { Self::Value(inner) => inner.serialize(serializer), @@ -775,13 +775,14 @@ where } } -impl<'a, T> Deserialize<'a> for ValueOrArray +#[cfg(feature = "serde")] +impl<'a, T> serde::Deserialize<'a> for ValueOrArray where - T: DeserializeOwned, + T: serde::de::DeserializeOwned, { fn deserialize(deserializer: D) -> Result where - D: Deserializer<'a>, + D: serde::Deserializer<'a>, { let value = serde_json::Value::deserialize(deserializer)?; @@ -789,7 +790,7 @@ where return Ok(Self::Array(Vec::new())); } - #[derive(Deserialize)] + #[derive(serde::Deserialize)] #[serde(untagged)] enum Variadic { Value(T), @@ -935,11 +936,12 @@ impl FilteredParams { } /// Response of the `eth_getFilterChanges` RPC. -#[derive(Default, Clone, Debug, PartialEq, Eq, Serialize)] -#[serde(untagged)] +#[derive(Default, Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "serde", serde(untagged))] pub enum FilterChanges { /// Empty result. - #[serde(with = "empty_array")] + #[cfg_attr(feature = "serde", serde(with = "empty_array"))] #[default] Empty, /// New logs. @@ -1017,6 +1019,7 @@ impl FilterChanges { } } +#[cfg(feature = "serde")] mod empty_array { use serde::{Serialize, Serializer}; @@ -1028,15 +1031,16 @@ mod empty_array { } } -impl<'de, T> Deserialize<'de> for FilterChanges +#[cfg(feature = "serde")] +impl<'de, T> serde::Deserialize<'de> for FilterChanges where - T: Deserialize<'de>, + T: serde::Deserialize<'de>, { fn deserialize(deserializer: D) -> Result where - D: Deserializer<'de>, + D: serde::Deserializer<'de>, { - #[derive(Deserialize)] + #[derive(serde::Deserialize)] #[serde(untagged)] enum Changes { Hashes(Vec), @@ -1073,9 +1077,10 @@ where } /// Owned equivalent of a `SubscriptionId` -#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] -#[serde(deny_unknown_fields)] -#[serde(untagged)] +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(deny_unknown_fields))] +#[cfg_attr(feature = "serde", serde(untagged))] pub enum FilterId { /// Numeric id Num(u64), @@ -1129,13 +1134,14 @@ pub enum PendingTransactionFilterKind { Full, } -impl Serialize for PendingTransactionFilterKind { +#[cfg(feature = "serde")] +impl serde::Serialize for PendingTransactionFilterKind { /// Serializes the `PendingTransactionFilterKind` into a boolean value: /// - `false` for `Hashes` /// - `true` for `Full` fn serialize(&self, serializer: S) -> Result where - S: Serializer, + S: serde::Serializer, { match self { Self::Hashes => false.serialize(serializer), @@ -1144,13 +1150,14 @@ impl Serialize for PendingTransactionFilterKind { } } -impl<'a> Deserialize<'a> for PendingTransactionFilterKind { +#[cfg(feature = "serde")] +impl<'a> serde::Deserialize<'a> for PendingTransactionFilterKind { /// Deserializes a boolean value into `PendingTransactionFilterKind`: /// - `false` becomes `Hashes` /// - `true` becomes `Full` fn deserialize(deserializer: D) -> Result where - D: Deserializer<'a>, + D: serde::Deserializer<'a>, { let val = Option::::deserialize(deserializer)?; match val { @@ -1165,11 +1172,13 @@ mod tests { use super::*; use serde_json::json; + #[cfg(feature = "serde")] fn serialize(t: &T) -> serde_json::Value { serde_json::to_value(t).expect("Failed to serialize value") } #[test] + #[cfg(feature = "serde")] fn test_empty_filter_topics_list() { let s = r#"{"fromBlock": "0xfc359e", "toBlock": "0xfc359e", "topics": [["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"], [], ["0x0000000000000000000000000c17e776cd218252adfca8d4e761d3fe757e9778"]]}"#; let filter = serde_json::from_str::(s).unwrap(); @@ -1216,6 +1225,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn test_block_hash() { let s = r#"{"blockHash":"0x58dc57ab582b282c143424bd01e8d923cddfdcda9455bad02a29522f6274a948"}"#; @@ -1231,6 +1241,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn test_filter_topics_middle_wildcard() { let s = r#"{"fromBlock": "0xfc359e", "toBlock": "0xfc359e", "topics": [["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925"], [], [null, "0x0000000000000000000000000c17e776cd218252adfca8d4e761d3fe757e9778"]]}"#; let filter = serde_json::from_str::(s).unwrap(); @@ -1249,8 +1260,9 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn can_serde_value_or_array() { - #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] + #[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)] struct Item { value: ValueOrArray, } @@ -1267,6 +1279,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn filter_serialization_test() { let t1 = "0000000000000000000000009729a6fbefefc8f6005933898b13dc45c3a2c8b7" .parse::() @@ -1506,6 +1519,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn can_convert_to_ethers_filter() { let json = json!( { @@ -1552,6 +1566,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn can_convert_to_ethers_filter_with_null_fields() { let json = json!( { diff --git a/crates/rpc-types-eth/src/index.rs b/crates/rpc-types-eth/src/index.rs index b583578670b..322591e08e7 100644 --- a/crates/rpc-types-eth/src/index.rs +++ b/crates/rpc-types-eth/src/index.rs @@ -1,10 +1,6 @@ use alloc::{format, string::String}; use alloy_primitives::U256; use core::fmt; -use serde::{ - de::{Error, Visitor}, - Deserialize, Deserializer, Serialize, Serializer, -}; /// A hex encoded or decimal index that's intended to be used as a rust index, hence it's /// deserialized into a `usize`. @@ -29,23 +25,25 @@ impl From for Index { } } -impl Serialize for Index { +#[cfg(feature = "serde")] +impl serde::Serialize for Index { fn serialize(&self, serializer: S) -> Result where - S: Serializer, + S: serde::Serializer, { serializer.serialize_str(&format!("0x{:x}", self.0)) } } -impl<'a> Deserialize<'a> for Index { +#[cfg(feature = "serde")] +impl<'a> serde::Deserialize<'a> for Index { fn deserialize(deserializer: D) -> Result where - D: Deserializer<'a>, + D: serde::Deserializer<'a>, { struct IndexVisitor; - impl<'a> Visitor<'a> for IndexVisitor { + impl<'a> serde::de::Visitor<'a> for IndexVisitor { type Value = Index; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -54,24 +52,26 @@ impl<'a> Deserialize<'a> for Index { fn visit_u64(self, value: u64) -> Result where - E: Error, + E: serde::de::Error, { Ok(Index(value as usize)) } fn visit_str(self, value: &str) -> Result where - E: Error, + E: serde::de::Error, { value.strip_prefix("0x").map_or_else( || { value.parse::().map(Index).map_err(|e| { - Error::custom(format!("Failed to parse numeric index: {e}")) + serde::de::Error::custom(format!("Failed to parse numeric index: {e}")) }) }, |val| { usize::from_str_radix(val, 16).map(Index).map_err(|e| { - Error::custom(format!("Failed to parse hex encoded index value: {e}")) + serde::de::Error::custom(format!( + "Failed to parse hex encoded index value: {e}" + )) }) }, ) @@ -79,7 +79,7 @@ impl<'a> Deserialize<'a> for Index { fn visit_string(self, value: String) -> Result where - E: Error, + E: serde::de::Error, { self.visit_str(value.as_ref()) } @@ -96,6 +96,7 @@ mod tests { use serde_json::json; #[test] + #[cfg(feature = "serde")] fn test_serde_index_rand() { let mut rng = thread_rng(); for _ in 0..100 { @@ -107,6 +108,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn test_serde_index_deserialization() { // Test decimal index let json_data = json!(42); diff --git a/crates/rpc-types-eth/src/log.rs b/crates/rpc-types-eth/src/log.rs index b1c4973cbab..9c15b67230b 100644 --- a/crates/rpc-types-eth/src/log.rs +++ b/crates/rpc-types-eth/src/log.rs @@ -1,36 +1,43 @@ use alloy_primitives::{Address, BlockHash, LogData, TxHash, B256}; -use serde::{Deserialize, Serialize}; /// Ethereum Log emitted by a transaction -#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] -#[serde(rename_all = "camelCase")] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct Log { - #[serde(flatten)] + #[cfg_attr(feature = "serde", serde(flatten))] /// Consensus log object pub inner: alloy_primitives::Log, /// Hash of the block the transaction that emitted this log was mined in pub block_hash: Option, /// Number of the block the transaction that emitted this log was mined in - #[serde(with = "alloy_serde::quantity::opt")] + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity::opt"))] pub block_number: Option, /// The timestamp of the block as proposed in: /// /// - #[serde(skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt", default)] + #[cfg_attr( + feature = "serde", + serde( + skip_serializing_if = "Option::is_none", + with = "alloy_serde::quantity::opt", + default + ) + )] pub block_timestamp: Option, /// Transaction Hash #[doc(alias = "tx_hash")] pub transaction_hash: Option, /// Index of the Transaction in the block - #[serde(with = "alloy_serde::quantity::opt")] + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity::opt"))] #[doc(alias = "tx_index")] pub transaction_index: Option, /// Log Index in Block - #[serde(with = "alloy_serde::quantity::opt")] + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity::opt"))] pub log_index: Option, /// Geth Compatibility Field: whether this log was removed - #[serde(default)] + #[cfg_attr(feature = "serde", serde(default))] pub removed: bool, } @@ -161,6 +168,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn serde_log() { let mut log = Log { inner: alloy_primitives::Log { diff --git a/crates/rpc-types-eth/src/pubsub.rs b/crates/rpc-types-eth/src/pubsub.rs index f6e1ea335f2..26606225504 100644 --- a/crates/rpc-types-eth/src/pubsub.rs +++ b/crates/rpc-types-eth/src/pubsub.rs @@ -4,11 +4,11 @@ use crate::{Filter, Header, Log, Transaction}; use alloc::{boxed::Box, format}; use alloy_primitives::B256; use alloy_serde::WithOtherFields; -use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer}; /// Subscription result. -#[derive(Clone, Debug, PartialEq, Eq, Deserialize)] -#[serde(untagged)] +#[derive(Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(untagged))] pub enum SubscriptionResult { /// New block header. Header(Box>), @@ -23,8 +23,9 @@ pub enum SubscriptionResult { } /// Response type for a SyncStatus subscription. -#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[serde(untagged)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(untagged))] pub enum PubSubSyncStatus { /// If not currently syncing, this should always be `false`. Simple(bool), @@ -33,8 +34,9 @@ pub enum PubSubSyncStatus { } /// Sync status metadata. -#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct SyncStatusMetadata { /// Whether the node is currently syncing. pub syncing: bool, @@ -43,17 +45,18 @@ pub struct SyncStatusMetadata { /// The current block. pub current_block: u64, /// The highest block. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub highest_block: Option, } -impl Serialize for SubscriptionResult +#[cfg(feature = "serde")] +impl serde::Serialize for SubscriptionResult where - T: Serialize, + T: serde::Serialize, { fn serialize(&self, serializer: S) -> Result where - S: Serializer, + S: serde::Serializer, { match *self { Self::Header(ref header) => header.serialize(serializer), @@ -66,9 +69,10 @@ where } /// Subscription kind. -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] -#[serde(deny_unknown_fields)] -#[serde(rename_all = "camelCase")] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] +#[cfg_attr(feature = "serde", serde(deny_unknown_fields))] pub enum SubscriptionKind { /// New block headers subscription. /// @@ -126,10 +130,11 @@ impl Params { } } -impl Serialize for Params { +#[cfg(feature = "serde")] +impl serde::Serialize for Params { fn serialize(&self, serializer: S) -> Result where - S: Serializer, + S: serde::Serializer, { match self { Self::None => (&[] as &[serde_json::Value]).serialize(serializer), @@ -139,11 +144,14 @@ impl Serialize for Params { } } -impl<'a> Deserialize<'a> for Params { +#[cfg(feature = "serde")] +impl<'a> serde::Deserialize<'a> for Params { fn deserialize(deserializer: D) -> Result where - D: Deserializer<'a>, + D: serde::Deserializer<'a>, { + use serde::de::Error; + let v = serde_json::Value::deserialize(deserializer)?; if v.is_null() { @@ -165,6 +173,7 @@ mod tests { use super::*; #[test] + #[cfg(feature = "serde")] fn params_serde() { let s: Params = serde_json::from_str("true").unwrap(); assert_eq!(s, Params::Bool(true)); diff --git a/crates/rpc-types-eth/src/simulate.rs b/crates/rpc-types-eth/src/simulate.rs index e325c89ca37..42247519229 100644 --- a/crates/rpc-types-eth/src/simulate.rs +++ b/crates/rpc-types-eth/src/simulate.rs @@ -3,7 +3,6 @@ use crate::{state::StateOverride, Block, BlockOverrides, Log, TransactionRequest}; use alloc::{string::String, vec::Vec}; use alloy_primitives::Bytes; -use serde::{Deserialize, Serialize}; /// The maximum number of blocks that can be simulated in a single request, pub const MAX_SIMULATE_BLOCKS: u64 = 256; @@ -11,25 +10,27 @@ pub const MAX_SIMULATE_BLOCKS: u64 = 256; /// Represents a batch of calls to be simulated sequentially within a block. /// This struct includes block and state overrides as well as the transaction requests to be /// executed. -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Clone, Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct SimBlock { /// Modifications to the default block characteristics. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub block_overrides: Option, /// State modifications to apply before executing the transactions. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub state_overrides: Option, /// A vector of transactions to be simulated. pub calls: Vec, } /// Represents the result of simulating a block. -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Clone, Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct SimulatedBlock { /// The simulated block. - #[serde(flatten)] + #[cfg_attr(feature = "serde", serde(flatten))] pub inner: B, /// A vector of results for each call in the block. pub calls: Vec, @@ -37,22 +38,23 @@ pub struct SimulatedBlock { /// Captures the outcome of a transaction simulation. /// It includes the return value, logs produced, gas used, and the status of the transaction. -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Clone, Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct SimCallResult { /// The raw bytes returned by the transaction. pub return_value: Bytes, /// Logs generated during the execution of the transaction. - #[serde(default)] + #[cfg_attr(feature = "serde", serde(default))] pub logs: Vec, /// The amount of gas used by the transaction. - #[serde(with = "alloy_serde::quantity")] + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))] pub gas_used: u64, /// The final status of the transaction, typically indicating success or failure. - #[serde(with = "alloy_serde::quantity")] + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))] pub status: bool, /// Error in case the call failed - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub error: Option, } @@ -60,24 +62,26 @@ pub struct SimCallResult { /// /// This struct configures how simulations are executed, including whether to trace token transfers, /// validate transaction sequences, and whether to return full transaction objects. -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Clone, Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct SimulatePayload { /// Array of block state calls to be executed at specific, optional block/state. pub block_state_calls: Vec, /// Flag to determine whether to trace ERC20/ERC721 token transfers within transactions. - #[serde(default)] + #[cfg_attr(feature = "serde", serde(default))] pub trace_transfers: bool, /// Flag to enable or disable validation of the transaction sequence in the blocks. - #[serde(default)] + #[cfg_attr(feature = "serde", serde(default))] pub validation: bool, /// Flag to decide if full transactions should be returned instead of just their hashes. pub return_full_transactions: bool, } /// The error response returned by the `eth_simulateV1` method. -#[derive(Clone, Debug, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Clone, Debug)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct SimulateError { /// Code error /// -3200: Execution reverted @@ -94,6 +98,7 @@ mod tests { use serde_json::json; #[test] + #[cfg(feature = "serde")] fn test_eth_simulate_v1_account_not_precompile() { let request_json = json!({ "jsonrpc": "2.0", diff --git a/crates/rpc-types-eth/src/state.rs b/crates/rpc-types-eth/src/state.rs index e9ee08511ee..8843edb06cf 100644 --- a/crates/rpc-types-eth/src/state.rs +++ b/crates/rpc-types-eth/src/state.rs @@ -3,36 +3,50 @@ use crate::{collections::HashMap, BlockOverrides}; use alloc::boxed::Box; use alloy_primitives::{Address, Bytes, B256, U256}; -use serde::{Deserialize, Serialize}; /// A set of account overrides pub type StateOverride = HashMap; /// Custom account override used in call -#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] -#[serde(default, rename_all = "camelCase", deny_unknown_fields)] +#[derive(Clone, Debug, Default, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(default, rename_all = "camelCase", deny_unknown_fields))] pub struct AccountOverride { /// Fake balance to set for the account before executing the call. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub balance: Option, /// Fake nonce to set for the account before executing the call. - #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] + #[cfg_attr( + feature = "serde", + serde( + default, + skip_serializing_if = "Option::is_none", + with = "alloy_serde::quantity::opt" + ) + )] pub nonce: Option, /// Fake EVM bytecode to inject into the account before executing the call. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub code: Option, /// Fake key-value mapping to override all slots in the account storage before executing the /// call. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub state: Option>, /// Fake key-value mapping to override individual slots in the account storage before executing /// the call. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub state_diff: Option>, /// Moves addresses precompile into the specified address. This move is done before the 'code' /// override is set. When the specified address is not a precompile, the behaviour is undefined /// and different clients might behave differently. - #[serde(default, skip_serializing_if = "Option::is_none", rename = "movePrecompileToAddress")] + #[cfg_attr( + feature = "serde", + serde( + default, + skip_serializing_if = "Option::is_none", + rename = "movePrecompileToAddress" + ) + )] pub move_precompile_to: Option
, } @@ -94,6 +108,17 @@ mod tests { use alloy_primitives::address; #[test] + fn test_default_account_override() { + let acc_override = AccountOverride::default(); + assert!(acc_override.balance.is_none()); + assert!(acc_override.nonce.is_none()); + assert!(acc_override.code.is_none()); + assert!(acc_override.state.is_none()); + assert!(acc_override.state_diff.is_none()); + } + + #[test] + #[cfg(feature = "serde")] #[should_panic(expected = "invalid type")] fn test_invalid_json_structure() { let invalid_json = r#"{ @@ -106,6 +131,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn test_large_values_in_override() { let large_values_json = r#"{ "0x1234567890123456789012345678901234567890": { @@ -122,16 +148,7 @@ mod tests { } #[test] - fn test_default_account_override() { - let acc_override = AccountOverride::default(); - assert!(acc_override.balance.is_none()); - assert!(acc_override.nonce.is_none()); - assert!(acc_override.code.is_none()); - assert!(acc_override.state.is_none()); - assert!(acc_override.state_diff.is_none()); - } - - #[test] + #[cfg(feature = "serde")] fn test_state_override() { let s = r#"{ "0x0000000000000000000000000000000000000124": { @@ -145,6 +162,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn test_state_override_state_diff() { let s = r#"{ "0x1b5212AF6b76113afD94cD2B5a78a73B7d7A8222": { diff --git a/crates/rpc-types-eth/src/syncing.rs b/crates/rpc-types-eth/src/syncing.rs index 2bfb26824d3..c61cc58c5ab 100644 --- a/crates/rpc-types-eth/src/syncing.rs +++ b/crates/rpc-types-eth/src/syncing.rs @@ -1,11 +1,10 @@ -use alloy_primitives::{B512, U256}; -use serde::{Deserialize, Deserializer, Serialize, Serializer}; - use alloc::{boxed::Box, collections::BTreeMap, string::String, vec::Vec}; +use alloy_primitives::{B512, U256}; /// Syncing info -#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Clone, Debug, Default, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct SyncInfo { /// Starting block pub starting_block: U256, @@ -19,24 +18,26 @@ pub struct SyncInfo { pub warp_chunks_processed: Option, /// The details of the sync stages as an hashmap /// where the key is the name of the stage and the value is the block number. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub stages: Option>, } /// The detail of the sync stages. -#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Clone, Debug, Default, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct Stage { /// The name of the sync stage. - #[serde(alias = "stage_name")] + #[cfg_attr(feature = "serde", serde(alias = "stage_name"))] pub name: String, /// Indicates the progress of the sync stage. - #[serde(alias = "block_number", with = "alloy_serde::quantity")] + #[cfg_attr(feature = "serde", serde(alias = "block_number", with = "alloy_serde::quantity"))] pub block: u64, } /// Peers info -#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize)] +#[derive(Clone, Debug, Default, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Peers { /// Number of active peers pub active: usize, @@ -49,7 +50,8 @@ pub struct Peers { } /// Peer connection information -#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct PeerInfo { /// Public node id pub id: Option, @@ -64,8 +66,9 @@ pub struct PeerInfo { } /// Peer network information -#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Clone, Debug, Default, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct PeerNetworkInfo { /// Remote endpoint address pub remote_address: String, @@ -74,17 +77,19 @@ pub struct PeerNetworkInfo { } /// Peer protocols information -#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct PeerProtocolsInfo { /// Ethereum protocol information pub eth: Option, /// PIP protocol information. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub pip: Option, } /// Peer Ethereum protocol information -#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct PeerEthProtocolInfo { /// Negotiated ethereum protocol version pub version: u32, @@ -95,7 +100,8 @@ pub struct PeerEthProtocolInfo { } /// Peer PIP protocol information -#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct PipProtocolInfo { /// Negotiated PIP protocol version pub version: u32, @@ -114,12 +120,13 @@ pub enum SyncStatus { None, } -impl<'de> Deserialize<'de> for SyncStatus { +#[cfg(feature = "serde")] +impl<'de> serde::Deserialize<'de> for SyncStatus { fn deserialize(deserializer: D) -> Result where - D: Deserializer<'de>, + D: serde::Deserializer<'de>, { - #[derive(Deserialize)] + #[derive(serde::Deserialize)] #[serde(untagged)] enum Syncing { /// When client is synced to the highest block, eth_syncing with return "false" @@ -137,10 +144,11 @@ impl<'de> Deserialize<'de> for SyncStatus { } } -impl Serialize for SyncStatus { +#[cfg(feature = "serde")] +impl serde::Serialize for SyncStatus { fn serialize(&self, serializer: S) -> Result where - S: Serializer, + S: serde::Serializer, { match self { Self::Info(info) => info.serialize(serializer), @@ -150,8 +158,9 @@ impl Serialize for SyncStatus { } /// Propagation statistics for pending transaction. -#[derive(Clone, Debug, Default, Serialize)] -#[serde(rename_all = "camelCase")] +#[derive(Clone, Debug, Default)] +#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] #[doc(alias = "TxStats")] pub struct TransactionStats { /// Block no this transaction was first seen. @@ -161,8 +170,9 @@ pub struct TransactionStats { } /// Chain status. -#[derive(Clone, Copy, Debug, Default, Serialize)] -#[serde(rename_all = "camelCase")] +#[derive(Clone, Copy, Debug, Default)] +#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct ChainStatus { /// Describes the gap in the blockchain, if there is one: (first, last) pub block_gap: Option<(U256, U256)>, diff --git a/crates/rpc-types-eth/src/transaction/mod.rs b/crates/rpc-types-eth/src/transaction/mod.rs index 3a46cfb3cc2..19e30d1cf7d 100644 --- a/crates/rpc-types-eth/src/transaction/mod.rs +++ b/crates/rpc-types-eth/src/transaction/mod.rs @@ -7,7 +7,6 @@ use alloy_consensus::{ use alloy_eips::eip7702::SignedAuthorization; use alloy_network_primitives::TransactionResponse; use alloy_primitives::{Address, BlockHash, Bytes, ChainId, TxHash, TxKind, B256, U256}; -use serde::{Deserialize, Serialize}; use alloc::vec::Vec; @@ -35,24 +34,25 @@ pub use signature::{Parity, Signature}; pub use alloy_consensus::{AnyReceiptEnvelope, Receipt, ReceiptEnvelope, ReceiptWithBloom}; /// Transaction object used in RPC -#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] -#[serde(rename_all = "camelCase")] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] #[doc(alias = "Tx")] pub struct Transaction { /// Hash pub hash: TxHash, /// Nonce - #[serde(with = "alloy_serde::quantity")] + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))] pub nonce: u64, /// Block hash - #[serde(default)] + #[cfg_attr(feature = "serde", serde(default))] pub block_hash: Option, /// Block number - #[serde(default, with = "alloy_serde::quantity::opt")] + #[cfg_attr(feature = "serde", serde(default, with = "alloy_serde::quantity::opt"))] pub block_number: Option, /// Transaction Index - #[serde(default, with = "alloy_serde::quantity::opt")] + #[cfg_attr(feature = "serde", serde(default, with = "alloy_serde::quantity::opt"))] pub transaction_index: Option, /// Sender pub from: Address, @@ -61,54 +61,92 @@ pub struct Transaction { /// Transferred value pub value: U256, /// Gas Price - #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] + #[cfg_attr( + feature = "serde", + serde( + default, + skip_serializing_if = "Option::is_none", + with = "alloy_serde::quantity::opt" + ) + )] pub gas_price: Option, /// Gas amount - #[serde(with = "alloy_serde::quantity")] + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))] pub gas: u128, /// Max BaseFeePerGas the user is willing to pay. - #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] + #[cfg_attr( + feature = "serde", + serde( + default, + skip_serializing_if = "Option::is_none", + with = "alloy_serde::quantity::opt" + ) + )] pub max_fee_per_gas: Option, /// The miner's tip. - #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] + #[cfg_attr( + feature = "serde", + serde( + default, + skip_serializing_if = "Option::is_none", + with = "alloy_serde::quantity::opt" + ) + )] pub max_priority_fee_per_gas: Option, /// Configured max fee per blob gas for eip-4844 transactions - #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] + #[cfg_attr( + feature = "serde", + serde( + default, + skip_serializing_if = "Option::is_none", + with = "alloy_serde::quantity::opt" + ) + )] pub max_fee_per_blob_gas: Option, /// Data pub input: Bytes, /// All _flattened_ fields of the transaction signature. /// /// Note: this is an option so special transaction types without a signature (e.g. ) can be supported. - #[serde(flatten, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(flatten, skip_serializing_if = "Option::is_none"))] pub signature: Option, /// The chain id of the transaction, if any. - #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] + #[cfg_attr( + feature = "serde", + serde( + default, + skip_serializing_if = "Option::is_none", + with = "alloy_serde::quantity::opt" + ) + )] pub chain_id: Option, /// Contains the blob hashes for eip-4844 transactions. - #[serde(skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] pub blob_versioned_hashes: Option>, /// EIP2930 /// /// Pre-pay to warm storage access. - #[serde(skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] pub access_list: Option, /// EIP2718 /// /// Transaction type, /// Some(4) for EIP-7702 transaction, Some(3) for EIP-4844 transaction, Some(2) for EIP-1559 /// transaction, Some(1) for AccessList transaction, None or Some(0) for Legacy - #[serde( - default, - rename = "type", - skip_serializing_if = "Option::is_none", - with = "alloy_serde::quantity::opt" + #[cfg_attr( + feature = "serde", + serde( + default, + rename = "type", + skip_serializing_if = "Option::is_none", + with = "alloy_serde::quantity::opt" + ) )] #[doc(alias = "tx_type")] pub transaction_type: Option, /// The signed authorization list is a list of tuples that store the address to code which the /// signer desires to execute in the context of their EOA and their signature. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub authorization_list: Option>, } @@ -339,6 +377,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn serde_transaction() { let transaction = Transaction { hash: B256::with_last_byte(1), @@ -382,6 +421,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn serde_transaction_with_parity_bit() { let transaction = Transaction { hash: B256::with_last_byte(1), @@ -425,6 +465,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn serde_minimal_transaction() { let transaction = Transaction { hash: B256::with_last_byte(1), @@ -445,6 +486,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn into_request_legacy() { // cast rpc eth_getTransactionByHash // 0xe9e91f1ee4b56c0df2e9f06c2b8c27c6076195a88a7b8537ba8313d80e6f124e --rpc-url mainnet @@ -457,6 +499,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn into_request_eip1559() { // cast rpc eth_getTransactionByHash // 0x0e07d8b53ed3d91314c80e53cf25bcde02084939395845cbb625b029d568135c --rpc-url mainnet diff --git a/crates/rpc-types-eth/src/transaction/receipt.rs b/crates/rpc-types-eth/src/transaction/receipt.rs index 7fb376734e9..2901e888f1a 100644 --- a/crates/rpc-types-eth/src/transaction/receipt.rs +++ b/crates/rpc-types-eth/src/transaction/receipt.rs @@ -4,7 +4,6 @@ use alloy_eips::eip7702::SignedAuthorization; use alloy_network_primitives::ReceiptResponse; use alloy_primitives::{Address, BlockHash, TxHash, B256}; use alloy_serde::WithOtherFields; -use serde::{Deserialize, Serialize}; use alloc::vec::Vec; @@ -12,42 +11,57 @@ use alloc::vec::Vec; /// /// This type is generic over an inner [`ReceiptEnvelope`] which contains /// consensus data and metadata. -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq)] #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] -#[serde(rename_all = "camelCase")] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] #[doc(alias = "TxReceipt")] pub struct TransactionReceipt> { /// The receipt envelope, which contains the consensus receipt data.. - #[serde(flatten)] + #[cfg_attr(feature = "serde", serde(flatten))] pub inner: T, /// Transaction Hash. #[doc(alias = "tx_hash")] pub transaction_hash: TxHash, /// Index within the block. - #[serde(default, with = "alloy_serde::quantity::opt")] + #[cfg_attr(feature = "serde", serde(default, with = "alloy_serde::quantity::opt"))] #[doc(alias = "tx_index")] pub transaction_index: Option, /// Hash of the block this transaction was included within. - #[serde(default)] + #[cfg_attr(feature = "serde", serde(default))] pub block_hash: Option, /// Number of the block this transaction was included within. - #[serde(default, with = "alloy_serde::quantity::opt")] + #[cfg_attr(feature = "serde", serde(default, with = "alloy_serde::quantity::opt"))] pub block_number: Option, /// Gas used by this transaction alone. - #[serde(with = "alloy_serde::quantity")] + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))] pub gas_used: u128, /// The price paid post-execution by the transaction (i.e. base fee + priority fee). Both /// fields in 1559-style transactions are maximums (max fee + max priority fee), the amount /// that's actually paid by users can only be determined post-execution - #[serde(with = "alloy_serde::quantity")] + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))] pub effective_gas_price: u128, /// Blob gas used by the eip-4844 transaction /// /// This is None for non eip-4844 transactions - #[serde(skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt", default)] + #[cfg_attr( + feature = "serde", + serde( + skip_serializing_if = "Option::is_none", + with = "alloy_serde::quantity::opt", + default + ) + )] pub blob_gas_used: Option, /// The price paid by the eip-4844 transaction per blob gas. - #[serde(skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt", default)] + #[cfg_attr( + feature = "serde", + serde( + skip_serializing_if = "Option::is_none", + with = "alloy_serde::quantity::opt", + default + ) + )] pub blob_gas_price: Option, /// Address of the sender pub from: Address, @@ -58,11 +72,11 @@ pub struct TransactionReceipt> { /// The post-transaction stateroot (pre Byzantium) /// /// EIP98 makes this optional field, if it's missing then skip serializing it - #[serde(skip_serializing_if = "Option::is_none", rename = "root")] + #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none", rename = "root"))] pub state_root: Option, /// The authorization list is a list of tuples that store the address to code which the signer /// desires to execute in the context of their EOA. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub authorization_list: Option>, } @@ -213,6 +227,7 @@ mod test { } #[test] + #[cfg(feature = "serde")] fn test_sanity() { let json_str = r#"{"transactionHash":"0x21f6554c28453a01e7276c1db2fc1695bb512b170818bfa98fa8136433100616","blockHash":"0x4acbdefb861ef4adedb135ca52865f6743451bfbfa35db78076f881a40401a5e","blockNumber":"0x129f4b9","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000200000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000800000000000000000000000000000000004000000000000000000800000000100000020000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000010000000000000000000000000000","gasUsed":"0xbde1","contractAddress":null,"cumulativeGasUsed":"0xa42aec","transactionIndex":"0x7f","from":"0x9a53bfba35269414f3b2d20b52ca01b15932c7b2","to":"0xdac17f958d2ee523a2206206994597c13d831ec7","type":"0x2","effectiveGasPrice":"0xfb0f6e8c9","logs":[{"blockHash":"0x4acbdefb861ef4adedb135ca52865f6743451bfbfa35db78076f881a40401a5e","address":"0xdac17f958d2ee523a2206206994597c13d831ec7","logIndex":"0x118","data":"0x00000000000000000000000000000000000000000052b7d2dcc80cd2e4000000","removed":false,"topics":["0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925","0x0000000000000000000000009a53bfba35269414f3b2d20b52ca01b15932c7b2","0x00000000000000000000000039e5dbb9d2fead31234d7c647d6ce77d85826f76"],"blockNumber":"0x129f4b9","transactionIndex":"0x7f","transactionHash":"0x21f6554c28453a01e7276c1db2fc1695bb512b170818bfa98fa8136433100616"}],"status":"0x1"}"#; @@ -256,9 +271,10 @@ mod test { } #[test] + #[cfg(feature = "serde")] fn deserialize_tx_receipt_op() { // OtherFields for Optimism - #[derive(Debug, Deserialize)] + #[derive(Debug, serde::Deserialize)] struct OpOtherFields { #[serde(rename = "l1BaseFeeScalar")] l1_base_fee_scalar: String, @@ -331,9 +347,10 @@ mod test { } #[test] + #[cfg(feature = "serde")] fn deserialize_tx_receipt_arb() { // OtherFields for Arbitrum - #[derive(Debug, Deserialize)] + #[derive(Debug, serde::Deserialize)] struct ArbOtherFields { #[serde(rename = "gasUsedForL1")] gas_used_for_l1: String, diff --git a/crates/rpc-types-eth/src/transaction/request.rs b/crates/rpc-types-eth/src/transaction/request.rs index c7938f5b8ce..424e7796934 100644 --- a/crates/rpc-types-eth/src/transaction/request.rs +++ b/crates/rpc-types-eth/src/transaction/request.rs @@ -8,7 +8,6 @@ use alloy_consensus::{ use alloy_eips::eip7702::SignedAuthorization; use alloy_primitives::{Address, Bytes, ChainId, TxKind, B256, U256}; use core::hash::Hash; -use serde::{Deserialize, Serialize}; use alloc::{ string::{String, ToString}, @@ -17,64 +16,120 @@ use alloc::{ }; /// Represents _all_ transaction requests to/from RPC. +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] -#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] #[doc(alias = "TxRequest")] pub struct TransactionRequest { /// The address of the transaction author. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub from: Option
, /// The destination address of the transaction. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub to: Option, /// The legacy gas price. - #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] + #[cfg_attr( + feature = "serde", + serde( + default, + skip_serializing_if = "Option::is_none", + with = "alloy_serde::quantity::opt" + ) + )] pub gas_price: Option, /// The max base fee per gas the sender is willing to pay. - #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] + #[cfg_attr( + feature = "serde", + serde( + default, + skip_serializing_if = "Option::is_none", + with = "alloy_serde::quantity::opt" + ) + )] pub max_fee_per_gas: Option, /// The max priority fee per gas the sender is willing to pay, also called the miner tip. - #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] + #[cfg_attr( + feature = "serde", + serde( + default, + skip_serializing_if = "Option::is_none", + with = "alloy_serde::quantity::opt" + ) + )] pub max_priority_fee_per_gas: Option, /// The max fee per blob gas for EIP-4844 blob transactions. - #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] + #[cfg_attr( + feature = "serde", + serde( + default, + skip_serializing_if = "Option::is_none", + with = "alloy_serde::quantity::opt" + ) + )] pub max_fee_per_blob_gas: Option, /// The gas limit for the transaction. - #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] + #[cfg_attr( + feature = "serde", + serde( + default, + skip_serializing_if = "Option::is_none", + with = "alloy_serde::quantity::opt" + ) + )] pub gas: Option, /// The value transferred in the transaction, in wei. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub value: Option, /// Transaction data. - #[serde(default, flatten)] + #[cfg_attr(feature = "serde", serde(default, flatten))] pub input: TransactionInput, /// The nonce of the transaction. - #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] + #[cfg_attr( + feature = "serde", + serde( + default, + skip_serializing_if = "Option::is_none", + with = "alloy_serde::quantity::opt" + ) + )] pub nonce: Option, /// The chain ID for the transaction. - #[serde(default, skip_serializing_if = "Option::is_none", with = "alloy_serde::quantity::opt")] + #[cfg_attr( + feature = "serde", + serde( + default, + skip_serializing_if = "Option::is_none", + with = "alloy_serde::quantity::opt" + ) + )] pub chain_id: Option, /// An EIP-2930 access list, which lowers cost for accessing accounts and storages in the list. See [EIP-2930](https://eips.ethereum.org/EIPS/eip-2930) for more information. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub access_list: Option, /// The EIP-2718 transaction type. See [EIP-2718](https://eips.ethereum.org/EIPS/eip-2718) for more information. - #[serde( - default, - rename = "type", - skip_serializing_if = "Option::is_none", - with = "alloy_serde::quantity::opt" + #[cfg_attr( + feature = "serde", + serde( + default, + rename = "type", + skip_serializing_if = "Option::is_none", + with = "alloy_serde::quantity::opt" + ) )] #[doc(alias = "tx_type")] pub transaction_type: Option, /// Blob versioned hashes for EIP-4844 transactions. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub blob_versioned_hashes: Option>, /// Blob sidecar for EIP-4844 transactions. - #[serde(default, flatten, skip_serializing_if = "Option::is_none")] + #[cfg_attr( + feature = "serde", + serde(default, flatten, skip_serializing_if = "Option::is_none") + )] pub sidecar: Option, /// Authorization list for for EIP-7702 transactions. - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub authorization_list: Option>, } @@ -610,16 +665,17 @@ impl TransactionRequest { /// If both fields are set, it is expected that they contain the same value, otherwise an error is /// returned. #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] -#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[doc(alias = "TxInput")] pub struct TransactionInput { /// Transaction data - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub input: Option, /// Transaction data /// /// This is the same as `input` but is used for backwards compatibility: - #[serde(default, skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] pub data: Option, } @@ -963,6 +1019,7 @@ mod tests { // #[test] + #[cfg(feature = "serde")] fn serde_from_to() { let s = r#"{"from":"0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "to":"0x70997970C51812dc3A010C7d01b50e0d17dc79C8" }"#; let req = serde_json::from_str::(s).unwrap(); @@ -970,12 +1027,14 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn serde_tx_request() { let s = r#"{"accessList":[],"data":"0x0902f1ac","to":"0xa478c2975ab1ea89e8196811f51a7b7ade33eb11","type":"0x02"}"#; let _req = serde_json::from_str::(s).unwrap(); } #[test] + #[cfg(feature = "serde")] fn serde_unique_call_input() { let s = r#"{"accessList":[],"data":"0x0902f1ac", "input":"0x0902f1ac","to":"0xa478c2975ab1ea89e8196811f51a7b7ade33eb11","type":"0x02"}"#; let req = serde_json::from_str::(s).unwrap(); @@ -995,6 +1054,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] 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(); @@ -1005,6 +1065,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn serde_tx_chain_id_field() { let chain_id: ChainId = 12345678; @@ -1018,6 +1079,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn serde_empty() { let tx = TransactionRequest::default(); let serialized = serde_json::to_string(&tx).unwrap(); @@ -1025,6 +1087,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn serde_tx_with_sidecar() { // Create a sidecar with some data. let s = r#"{ diff --git a/crates/rpc-types-eth/src/transaction/signature.rs b/crates/rpc-types-eth/src/transaction/signature.rs index 8a32476c575..29cde635399 100644 --- a/crates/rpc-types-eth/src/transaction/signature.rs +++ b/crates/rpc-types-eth/src/transaction/signature.rs @@ -1,12 +1,12 @@ //! Signature related RPC values use alloy_primitives::U256; -use serde::{Deserialize, Serialize}; use alloc::{format, string::String}; /// Container type for all signature fields in RPC #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] -#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Signature { /// The R field of the signature; the point on the curve. pub r: U256, @@ -22,7 +22,10 @@ pub struct Signature { /// See also and pub v: U256, /// The y parity of the signature. This is only used for typed (non-legacy) transactions. - #[serde(default, rename = "yParity", skip_serializing_if = "Option::is_none")] + #[cfg_attr( + feature = "serde", + serde(default, rename = "yParity", skip_serializing_if = "Option::is_none") + )] pub y_parity: Option, } @@ -30,9 +33,14 @@ pub struct Signature { /// /// This will be serialized as "0x0" if false, and "0x1" if true. #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] -#[derive(Default, Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Default, Clone, Copy, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct Parity( - #[serde(serialize_with = "serialize_parity", deserialize_with = "deserialize_parity")] pub bool, + #[cfg_attr( + feature = "serde", + serde(serialize_with = "serialize_parity", deserialize_with = "deserialize_parity") + )] + pub bool, ); impl From for Parity { @@ -41,6 +49,7 @@ impl From for Parity { } } +#[cfg(feature = "serde")] fn serialize_parity(parity: &bool, serializer: S) -> Result where S: serde::Serializer, @@ -49,10 +58,12 @@ where } /// This implementation disallows serialization of the y parity bit that are not `"0x0"` or `"0x1"`. +#[cfg(feature = "serde")] fn deserialize_parity<'de, D>(deserializer: D) -> Result where D: serde::Deserializer<'de>, { + use serde::Deserialize; let s = String::deserialize(deserializer)?; match s.as_str() { "0x0" => Ok(false), @@ -94,6 +105,7 @@ mod tests { use core::str::FromStr; #[test] + #[cfg(feature = "serde")] fn deserialize_without_parity() { let raw_signature_without_y_parity = r#"{ "r":"0xc569c92f176a3be1a6352dd5005bfc751dcb32f57623dd2a23693e64bf4447b0", @@ -115,6 +127,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn deserialize_with_parity() { let raw_signature_with_y_parity = r#"{ "r":"0xc569c92f176a3be1a6352dd5005bfc751dcb32f57623dd2a23693e64bf4447b0", @@ -137,6 +150,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn serialize_both_parity() { // this test should be removed if the struct moves to an enum based on tx type let signature = Signature { @@ -156,6 +170,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn serialize_v_only() { // this test should be removed if the struct moves to an enum based on tx type let signature = Signature { @@ -174,6 +189,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn serialize_parity() { let parity = Parity(true); let serialized = serde_json::to_string(&parity).unwrap(); @@ -185,6 +201,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn deserialize_parity() { let raw_parity = r#""0x1""#; let parity: Parity = serde_json::from_str(raw_parity).unwrap(); @@ -196,6 +213,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn deserialize_parity_invalid() { let raw_parity = r#""0x2""#; let parity: Result = serde_json::from_str(raw_parity); diff --git a/crates/rpc-types-eth/src/work.rs b/crates/rpc-types-eth/src/work.rs index cf8ec8666a7..1120b6bf9fb 100644 --- a/crates/rpc-types-eth/src/work.rs +++ b/crates/rpc-types-eth/src/work.rs @@ -1,9 +1,5 @@ use alloy_primitives::{B256, U256}; use core::fmt; -use serde::{ - de::{Error, SeqAccess, Visitor}, - Deserialize, Deserializer, Serialize, Serializer, -}; /// The result of an `eth_getWork` request #[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] @@ -18,10 +14,11 @@ pub struct Work { pub number: Option, } -impl Serialize for Work { +#[cfg(feature = "serde")] +impl serde::Serialize for Work { fn serialize(&self, s: S) -> Result where - S: Serializer, + S: serde::Serializer, { match self.number.as_ref() { Some(num) => { @@ -32,14 +29,15 @@ impl Serialize for Work { } } -impl<'a> Deserialize<'a> for Work { +#[cfg(feature = "serde")] +impl<'a> serde::Deserialize<'a> for Work { fn deserialize(deserializer: D) -> Result where - D: Deserializer<'a>, + D: serde::Deserializer<'a>, { struct WorkVisitor; - impl<'a> Visitor<'a> for WorkVisitor { + impl<'a> serde::de::Visitor<'a> for WorkVisitor { type Value = Work; fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -48,8 +46,9 @@ impl<'a> Deserialize<'a> for Work { fn visit_seq(self, mut seq: A) -> Result where - A: SeqAccess<'a>, + A: serde::de::SeqAccess<'a>, { + use serde::de::Error; let pow_hash = seq .next_element::()? .ok_or_else(|| A::Error::custom("missing pow hash"))?; diff --git a/crates/rpc-types-trace/Cargo.toml b/crates/rpc-types-trace/Cargo.toml index cdd3e7322b8..993e7a447b8 100644 --- a/crates/rpc-types-trace/Cargo.toml +++ b/crates/rpc-types-trace/Cargo.toml @@ -20,7 +20,7 @@ workspace = true [dependencies] alloy-primitives = { workspace = true, features = ["rlp", "serde"] } -alloy-rpc-types-eth = { workspace = true, features = ["std"] } +alloy-rpc-types-eth = { workspace = true, features = ["std", "serde"] } alloy-serde.workspace = true serde.workspace = true diff --git a/crates/signer-trezor/Cargo.toml b/crates/signer-trezor/Cargo.toml index eb71768d570..2258a1b326b 100644 --- a/crates/signer-trezor/Cargo.toml +++ b/crates/signer-trezor/Cargo.toml @@ -34,5 +34,5 @@ thiserror.workspace = true tracing.workspace = true [dev-dependencies] -alloy-rpc-types-eth.workspace = true +alloy-rpc-types-eth = { workspace = true, features = ["std", "serde"] } tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } From e7ea61da8c7336bbd7b148deb4fc1ab9081de729 Mon Sep 17 00:00:00 2001 From: refcell Date: Fri, 13 Sep 2024 07:29:02 -0400 Subject: [PATCH 168/186] feat(engine): Optional Serde (#1283) * feat: optional serde * fix: beacon types * fix: provider * fix: eip7547 * fix: run ci --- crates/eip7547/Cargo.toml | 2 +- crates/provider/Cargo.toml | 2 +- crates/rpc-types-beacon/Cargo.toml | 2 +- crates/rpc-types-engine/Cargo.toml | 9 +- crates/rpc-types-engine/src/cancun.rs | 3 +- crates/rpc-types-engine/src/forkchoice.rs | 11 +- crates/rpc-types-engine/src/identification.rs | 10 +- crates/rpc-types-engine/src/jwt.rs | 14 +- crates/rpc-types-engine/src/payload.rs | 136 +++++++++++------- crates/rpc-types-engine/src/transition.rs | 8 +- 10 files changed, 121 insertions(+), 76 deletions(-) diff --git a/crates/eip7547/Cargo.toml b/crates/eip7547/Cargo.toml index 3a576ec249a..45682d7a3bd 100644 --- a/crates/eip7547/Cargo.toml +++ b/crates/eip7547/Cargo.toml @@ -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 diff --git a/crates/provider/Cargo.toml b/crates/provider/Cargo.toml index e7a3b4c106a..a2fc9d81338 100644 --- a/crates/provider/Cargo.toml +++ b/crates/provider/Cargo.toml @@ -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 } diff --git a/crates/rpc-types-beacon/Cargo.toml b/crates/rpc-types-beacon/Cargo.toml index 092a533626a..9de616cbf8b 100644 --- a/crates/rpc-types-beacon/Cargo.toml +++ b/crates/rpc-types-beacon/Cargo.toml @@ -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 diff --git a/crates/rpc-types-engine/Cargo.toml b/crates/rpc-types-engine/Cargo.toml index 10b271d52c5..d4b68d91764 100644 --- a/crates/rpc-types-engine/Cargo.toml +++ b/crates/rpc-types-engine/Cargo.toml @@ -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 } @@ -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"] diff --git a/crates/rpc-types-engine/src/cancun.rs b/crates/rpc-types-engine/src/cancun.rs index bdef54daa6d..28fc6ad0aa0 100644 --- a/crates/rpc-types-engine/src/cancun.rs +++ b/crates/rpc-types-engine/src/cancun.rs @@ -10,7 +10,8 @@ use alloy_primitives::B256; /// /// See also: /// -#[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, diff --git a/crates/rpc-types-engine/src/forkchoice.rs b/crates/rpc-types-engine/src/forkchoice.rs index 628e682d2cd..a2af9b753f0 100644 --- a/crates/rpc-types-engine/src/forkchoice.rs +++ b/crates/rpc-types-engine/src/forkchoice.rs @@ -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; @@ -19,8 +18,9 @@ pub const INVALID_PAYLOAD_ATTRIBUTES_ERROR_MSG: &str = "Invalid payload attribut pub type ForkChoiceUpdateResult = Result; /// 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, @@ -116,8 +116,9 @@ impl From 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. diff --git a/crates/rpc-types-engine/src/identification.rs b/crates/rpc-types-engine/src/identification.rs index bf3248b2e3d..beefb5a4ed7 100644 --- a/crates/rpc-types-engine/src/identification.rs +++ b/crates/rpc-types-engine/src/identification.rs @@ -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, @@ -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, @@ -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(); diff --git a/crates/rpc-types-engine/src/jwt.rs b/crates/rpc-types-engine/src/jwt.rs index dbc70d880f6..768ee132da1 100644 --- a/crates/rpc-types-engine/src/jwt.rs +++ b/crates/rpc-types-engine/src/jwt.rs @@ -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, @@ -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 @@ -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. @@ -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 { let bytes = &self.0; let key = jsonwebtoken::EncodingKey::from_secret(bytes); @@ -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) }; @@ -342,6 +345,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn validation_with_current_time_ok() { let secret = JwtSecret::random(); let claims = Claims::default(); @@ -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(); @@ -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) }; @@ -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) }; @@ -402,6 +408,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn validation_error_unsupported_algorithm() { let secret = JwtSecret::random(); let bytes = &secret.0; @@ -417,6 +424,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn valid_without_exp_claim() { let secret = JwtSecret::random(); diff --git a/crates/rpc-types-engine/src/payload.rs b/crates/rpc-types-engine/src/payload.rs index e9fc819fa3a..ba33c8dd51a 100644 --- a/crates/rpc-types-engine/src/payload.rs +++ b/crates/rpc-types-engine/src/payload.rs @@ -11,7 +11,6 @@ use alloy_eips::{ }; use alloy_primitives::{Address, Bloom, Bytes, B256, B64, U256}; use core::iter::{FromIterator, IntoIterator}; -use serde::{ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer}; /// The execution payload body response that allows for `null` values. pub type ExecutionPayloadBodiesV1 = Vec>; @@ -20,7 +19,8 @@ pub type ExecutionPayloadBodiesV1 = Vec>; pub type ExecutionPayloadBodiesV2 = Vec>; /// And 8-byte identifier for an execution payload. -#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct PayloadId(pub B64); // === impl PayloadId === @@ -49,8 +49,9 @@ impl core::fmt::Display for PayloadId { /// /// See: /// -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[serde(untagged)] +#[derive(Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(untagged))] pub enum ExecutionPayloadFieldV2 { /// V1 payload V1(ExecutionPayloadV1), @@ -69,14 +70,15 @@ impl ExecutionPayloadFieldV2 { } /// This is the input to `engine_newPayloadV2`, which may or may not have a withdrawals field. -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] +#[derive(Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase", deny_unknown_fields))] pub struct ExecutionPayloadInputV2 { /// The V1 execution payload - #[serde(flatten)] + #[cfg_attr(feature = "serde", serde(flatten))] pub execution_payload: ExecutionPayloadV1, /// The payload withdrawals - #[serde(skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] pub withdrawals: Option>, } @@ -85,8 +87,9 @@ pub struct ExecutionPayloadInputV2 { /// /// See also: /// -#[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 ExecutionPayloadEnvelopeV2 { /// Execution payload, which could be either V1 or V2 /// @@ -112,8 +115,9 @@ impl ExecutionPayloadEnvelopeV2 { /// /// See also: /// -#[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 ExecutionPayloadEnvelopeV3 { /// Execution payload V3 pub execution_payload: ExecutionPayloadV3, @@ -131,8 +135,9 @@ pub struct ExecutionPayloadEnvelopeV3 { /// /// See also: /// -#[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 ExecutionPayloadEnvelopeV4 { /// Execution payload V4 pub execution_payload: ExecutionPayloadV4, @@ -148,9 +153,10 @@ pub struct ExecutionPayloadEnvelopeV4 { /// This structure maps on the ExecutionPayload structure of the beacon chain spec. /// /// See also: -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "ssz", derive(ssz_derive::Encode, ssz_derive::Decode))] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct ExecutionPayloadV1 { /// The parent hash of the block. pub parent_hash: B256, @@ -165,16 +171,16 @@ pub struct ExecutionPayloadV1 { /// The previous randao of the block. pub prev_randao: B256, /// The block number. - #[serde(with = "alloy_serde::quantity")] + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))] pub block_number: u64, /// The gas limit of the block. - #[serde(with = "alloy_serde::quantity")] + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))] pub gas_limit: u64, /// The gas used of the block. - #[serde(with = "alloy_serde::quantity")] + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))] pub gas_used: u64, /// The timestamp of the block. - #[serde(with = "alloy_serde::quantity")] + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))] pub timestamp: u64, /// The extra data of the block. pub extra_data: Bytes, @@ -189,11 +195,12 @@ pub struct ExecutionPayloadV1 { /// This structure maps on the ExecutionPayloadV2 structure of the beacon chain spec. /// /// See also: -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase", deny_unknown_fields)] +#[derive(Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase", deny_unknown_fields))] pub struct ExecutionPayloadV2 { /// Inner V1 payload - #[serde(flatten)] + #[cfg_attr(feature = "serde", serde(flatten))] pub payload_inner: ExecutionPayloadV1, /// Array of [`Withdrawal`] enabled with V2 @@ -302,20 +309,21 @@ impl ssz::Encode for ExecutionPayloadV2 { /// This structure maps on the ExecutionPayloadV3 structure of the beacon chain spec. /// /// See also: -#[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 ExecutionPayloadV3 { /// Inner V2 payload - #[serde(flatten)] + #[cfg_attr(feature = "serde", serde(flatten))] pub payload_inner: ExecutionPayloadV2, /// Array of hex [`u64`] representing blob gas used, enabled with V3 /// See - #[serde(with = "alloy_serde::quantity")] + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))] pub blob_gas_used: u64, /// Array of hex[`u64`] representing excess blob gas, enabled with V3 /// See - #[serde(with = "alloy_serde::quantity")] + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))] pub excess_blob_gas: u64, } @@ -435,11 +443,12 @@ impl ssz::Encode for ExecutionPayloadV3 { /// /// This structure has the syntax of ExecutionPayloadV3 and appends the new fields: depositRequests /// and withdrawalRequests. -#[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 ExecutionPayloadV4 { /// Inner V3 payload - #[serde(flatten)] + #[cfg_attr(feature = "serde", serde(flatten))] pub payload_inner: ExecutionPayloadV3, /// Array of deposit requests. /// @@ -468,7 +477,8 @@ impl ExecutionPayloadV4 { } /// This includes all bundled blob related data of an executed payload. -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct BlobsBundleV1 { /// All commitments in the bundle. pub commitments: Vec, @@ -594,8 +604,9 @@ impl FromIterator for BlobsBundleV1 { /// An execution payload, which can be either [ExecutionPayloadV1], [ExecutionPayloadV2], or /// [ExecutionPayloadV3]. -#[derive(Clone, Debug, PartialEq, Eq, Serialize)] -#[serde(untagged)] +#[derive(Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize))] +#[cfg_attr(feature = "serde", serde(untagged))] pub enum ExecutionPayload { /// V1 payload V1(ExecutionPayloadV1), @@ -751,12 +762,13 @@ impl From for ExecutionPayload { } // Deserializes untagged ExecutionPayload by trying each variant in falling order -impl<'de> Deserialize<'de> for ExecutionPayload { +#[cfg(feature = "serde")] +impl<'de> serde::Deserialize<'de> for ExecutionPayload { fn deserialize(deserializer: D) -> Result where - D: Deserializer<'de>, + D: serde::Deserializer<'de>, { - #[derive(Deserialize)] + #[derive(serde::Deserialize)] #[serde(untagged)] enum ExecutionPayloadDesc { V4(ExecutionPayloadV4), @@ -867,7 +879,8 @@ impl PayloadError { /// This structure contains a body of an execution payload. /// /// See also: -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct ExecutionPayloadBodyV1 { /// Enveloped encoded transactions. pub transactions: Vec, @@ -881,8 +894,9 @@ pub struct ExecutionPayloadBodyV1 { /// depositRequests and withdrawalRequests. /// /// See also: -#[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 ExecutionPayloadBodyV2 { /// Enveloped encoded transactions. pub transactions: Vec, @@ -906,11 +920,12 @@ pub struct ExecutionPayloadBodyV2 { /// This structure contains the attributes required to initiate a payload build process in the /// context of an `engine_forkchoiceUpdated` call. -#[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 PayloadAttributes { /// Value for the `timestamp` field of the new payload - #[serde(with = "alloy_serde::quantity")] + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))] pub timestamp: u64, /// Value for the `prevRandao` field of the new payload pub prev_randao: B256, @@ -918,21 +933,22 @@ pub struct PayloadAttributes { pub suggested_fee_recipient: Address, /// Array of [`Withdrawal`] enabled with V2 /// See - #[serde(skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] pub withdrawals: Option>, /// Root of the parent beacon block enabled with V3. /// /// See also - #[serde(skip_serializing_if = "Option::is_none")] + #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))] pub parent_beacon_block_root: Option, } /// This structure contains the result of processing a payload or fork choice update. -#[derive(Clone, Debug, PartialEq, Eq, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct PayloadStatus { /// The status of the payload. - #[serde(flatten)] + #[cfg_attr(feature = "serde", serde(flatten))] pub status: PayloadStatusEnum, /// Hash of the most recent valid block in the branch defined by payload and its ancestors pub latest_valid_hash: Option, @@ -987,11 +1003,13 @@ impl core::fmt::Display for PayloadStatus { } } -impl Serialize for PayloadStatus { +#[cfg(feature = "serde")] +impl serde::Serialize for PayloadStatus { fn serialize(&self, serializer: S) -> Result where - S: Serializer, + S: serde::Serializer, { + use serde::ser::SerializeMap; let mut map = serializer.serialize_map(Some(3))?; map.serialize_entry("status", self.status.as_str())?; map.serialize_entry("latestValidHash", &self.latest_valid_hash)?; @@ -1007,8 +1025,9 @@ impl From for PayloadStatusEnum { } /// Represents the status response of a payload. -#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] -#[serde(tag = "status", rename_all = "SCREAMING_SNAKE_CASE")] +#[derive(Clone, Debug, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(tag = "status", rename_all = "SCREAMING_SNAKE_CASE"))] pub enum PayloadStatusEnum { /// VALID is returned by the engine API in the following calls: /// - newPayload: if the payload was already known or was just validated and executed @@ -1020,7 +1039,7 @@ pub enum PayloadStatusEnum { /// - forkchoiceUpdate: if the new head is unknown, pre-merge, or reorg to it fails Invalid { /// The error message for the invalid payload. - #[serde(rename = "validationError")] + #[cfg_attr(feature = "serde", serde(rename = "validationError"))] validation_error: String, }, @@ -1112,6 +1131,7 @@ mod tests { use alloc::vec; #[test] + #[cfg(feature = "serde")] fn serde_payload_status() { let s = r#"{"status":"SYNCING","latestValidHash":null,"validationError":null}"#; let status: PayloadStatus = serde_json::from_str(s).unwrap(); @@ -1130,6 +1150,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn serde_payload_status_error_deserialize() { let s = r#"{"status":"INVALID","latestValidHash":null,"validationError":"Failed to decode block"}"#; let q = PayloadStatus { @@ -1178,6 +1199,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn serde_roundtrip_legacy_txs_payload_v1() { // pulled from hive 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"]}"#; @@ -1189,6 +1211,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn serde_roundtrip_legacy_txs_payload_v3() { // pulled from hive tests - modified with 4844 fields 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"}"#; @@ -1200,6 +1223,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn serde_roundtrip_enveloped_txs_payload_v1() { // pulled from hive 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"]}"#; @@ -1211,6 +1235,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn serde_roundtrip_enveloped_txs_payload_v3() { // pulled from hive tests - modified with 4844 fields 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"}"#; @@ -1222,6 +1247,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn serde_roundtrip_execution_payload_envelope_v3() { // pulled from a geth response getPayloadV3 in hive tests let response = r#"{"executionPayload":{"parentHash":"0xe927a1448525fb5d32cb50ee1408461a945ba6c39bd5cf5621407d500ecc8de9","feeRecipient":"0x0000000000000000000000000000000000000000","stateRoot":"0x10f8a0830000e8edef6d00cc727ff833f064b1950afd591ae41357f97e543119","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","prevRandao":"0xe0d8b4521a7da1582a713244ffb6a86aa1726932087386e2dc7973f43fc6cb24","blockNumber":"0x1","gasLimit":"0x2ffbd2","gasUsed":"0x0","timestamp":"0x1235","extraData":"0xd883010d00846765746888676f312e32312e30856c696e7578","baseFeePerGas":"0x342770c0","blockHash":"0x44d0fa5f2f73a938ebb96a2a21679eb8dea3e7b7dd8fd9f35aa756dda8bf0a8a","transactions":[],"withdrawals":[],"blobGasUsed":"0x0","excessBlobGas":"0x0"},"blockValue":"0x0","blobsBundle":{"commitments":[],"proofs":[],"blobs":[]},"shouldOverrideBuilder":false}"#; @@ -1230,6 +1256,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn serde_deserialize_execution_payload_input_v2() { let response = r#" { @@ -1290,6 +1317,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn serde_deserialize_v3_with_unknown_fields() { let input = r#" { @@ -1373,6 +1401,7 @@ mod tests { } #[test] + #[cfg(feature = "serde")] fn serde_deserialize_v2_input_with_blob_fields() { let input = r#" { @@ -1404,6 +1433,7 @@ mod tests { // #[test] + #[cfg(feature = "serde")] fn deserialize_op_base_payload() { let payload = r#"{"parentHash":"0x24e8df372a61cdcdb1a163b52aaa1785e0c869d28c3b742ac09e826bbb524723","feeRecipient":"0x4200000000000000000000000000000000000011","stateRoot":"0x9a5db45897f1ff1e620a6c14b0a6f1b3bcdbed59f2adc516a34c9a9d6baafa71","receiptsRoot":"0x8af6f74835d47835deb5628ca941d00e0c9fd75585f26dabdcb280ec7122e6af","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","prevRandao":"0xf37b24eeff594848072a05f74c8600001706c83e489a9132e55bf43a236e42ec","blockNumber":"0xe3d5d8","gasLimit":"0x17d7840","gasUsed":"0xb705","timestamp":"0x65a118c0","extraData":"0x","baseFeePerGas":"0x7a0ff32","blockHash":"0xf5c147b2d60a519b72434f0a8e082e18599021294dd9085d7597b0ffa638f1c0","withdrawals":[],"transactions":["0x7ef90159a05ba0034ffdcb246703298224564720b66964a6a69d0d7e9ffd970c546f7c048094deaddeaddeaddeaddeaddeaddeaddeaddead00019442000000000000000000000000000000000000158080830f424080b90104015d8eb900000000000000000000000000000000000000000000000000000000009e1c4a0000000000000000000000000000000000000000000000000000000065a11748000000000000000000000000000000000000000000000000000000000000000a4b479e5fa8d52dd20a8a66e468b56e993bdbffcccf729223aabff06299ab36db000000000000000000000000000000000000000000000000000000000000000400000000000000000000000073b4168cc87f35cc239200a20eb841cded23493b000000000000000000000000000000000000000000000000000000000000083400000000000000000000000000000000000000000000000000000000000f4240"]}"#; let _payload = serde_json::from_str::(payload).unwrap(); diff --git a/crates/rpc-types-engine/src/transition.rs b/crates/rpc-types-engine/src/transition.rs index a63cdf3f596..0e2aedfc121 100644 --- a/crates/rpc-types-engine/src/transition.rs +++ b/crates/rpc-types-engine/src/transition.rs @@ -1,9 +1,9 @@ use alloy_primitives::{B256, U256}; -use serde::{Deserialize, Serialize}; /// This structure contains configurable settings of the transition process. -#[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"))] #[doc(alias = "TxConfiguration")] pub struct TransitionConfiguration { /// Maps on the TERMINAL_TOTAL_DIFFICULTY parameter of EIP-3675 @@ -11,6 +11,6 @@ pub struct TransitionConfiguration { /// Maps on TERMINAL_BLOCK_HASH parameter of EIP-3675 pub terminal_block_hash: B256, /// Maps on TERMINAL_BLOCK_NUMBER parameter of EIP-3675 - #[serde(with = "alloy_serde::quantity")] + #[cfg_attr(feature = "serde", serde(with = "alloy_serde::quantity"))] pub terminal_block_number: u64, } From 4545172abcbf375d9bfc87ede87c6b0648443dec Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Fri, 13 Sep 2024 16:46:41 +0200 Subject: [PATCH 169/186] chore: release 0.3.4 --- CHANGELOG.md | 30 ++++++++++++++++++++++++++ Cargo.toml | 2 +- crates/alloy/CHANGELOG.md | 6 ++++++ crates/consensus/CHANGELOG.md | 12 +++++++++++ crates/contract/CHANGELOG.md | 12 +++++++++++ crates/eip7547/CHANGELOG.md | 12 +++++++++++ crates/eips/CHANGELOG.md | 11 ++++++++++ crates/genesis/CHANGELOG.md | 6 ++++++ crates/json-rpc/CHANGELOG.md | 6 ++++++ crates/network-primitives/CHANGELOG.md | 16 ++++++++++++++ crates/network/CHANGELOG.md | 12 +++++++++++ crates/node-bindings/CHANGELOG.md | 14 ++++++++++++ crates/provider/CHANGELOG.md | 19 ++++++++++++++++ crates/pubsub/CHANGELOG.md | 6 ++++++ crates/rpc-client/CHANGELOG.md | 12 +++++++++++ crates/rpc-types-admin/CHANGELOG.md | 6 ++++++ crates/rpc-types-anvil/CHANGELOG.md | 6 ++++++ crates/rpc-types-beacon/CHANGELOG.md | 12 +++++++++++ crates/rpc-types-debug/CHANGELOG.md | 6 ++++++ crates/rpc-types-engine/CHANGELOG.md | 17 +++++++++++++++ crates/rpc-types-eth/CHANGELOG.md | 17 +++++++++++++++ crates/rpc-types-mev/CHANGELOG.md | 6 ++++++ crates/rpc-types-trace/CHANGELOG.md | 11 ++++++++++ crates/rpc-types-txpool/CHANGELOG.md | 6 ++++++ crates/rpc-types/CHANGELOG.md | 12 +++++++++++ crates/serde/CHANGELOG.md | 6 ++++++ crates/signer-aws/CHANGELOG.md | 6 ++++++ crates/signer-gcp/CHANGELOG.md | 6 ++++++ crates/signer-ledger/CHANGELOG.md | 6 ++++++ crates/signer-local/CHANGELOG.md | 6 ++++++ crates/signer-trezor/CHANGELOG.md | 12 +++++++++++ crates/signer/CHANGELOG.md | 6 ++++++ crates/transport-http/CHANGELOG.md | 6 ++++++ crates/transport-ipc/CHANGELOG.md | 6 ++++++ crates/transport-ws/CHANGELOG.md | 6 ++++++ crates/transport/CHANGELOG.md | 6 ++++++ 36 files changed, 346 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fe15ae36cfa..abe75d70677 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,35 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Bug Fixes + +- `debug_traceCallMany` and `trace_callMany` ([#1278](https://github.com/alloy-rs/alloy/issues/1278)) +- Serde for `eth_simulateV1` ([#1273](https://github.com/alloy-rs/alloy/issues/1273)) + +### Features + +- [engine] Optional Serde ([#1283](https://github.com/alloy-rs/alloy/issues/1283)) +- [alloy-rpc-types-eth] Optional serde ([#1276](https://github.com/alloy-rs/alloy/issues/1276)) +- Improve node bindings ([#1279](https://github.com/alloy-rs/alloy/issues/1279)) +- Add serde for NumHash ([#1277](https://github.com/alloy-rs/alloy/issues/1277)) +- [engine] No_std engine types ([#1268](https://github.com/alloy-rs/alloy/issues/1268)) +- No_std eth rpc types ([#1252](https://github.com/alloy-rs/alloy/issues/1252)) + +### Miscellaneous Tasks + +- Remove eth rpc types dep from engine types ([#1280](https://github.com/alloy-rs/alloy/issues/1280)) +- Swap `BlockHashOrNumber` alias and struct name ([#1270](https://github.com/alloy-rs/alloy/issues/1270)) +- [consensus] Remove Header Method ([#1271](https://github.com/alloy-rs/alloy/issues/1271)) +- [consensus] Alloc by Default ([#1272](https://github.com/alloy-rs/alloy/issues/1272)) +- [network-primitives] Remove alloc Vec Dep ([#1267](https://github.com/alloy-rs/alloy/issues/1267)) + +### Other + +- Add trait methods `cumulative_gas_used` and `state_root` to `ReceiptResponse` ([#1275](https://github.com/alloy-rs/alloy/issues/1275)) +- Implement `seal` helper for `Header` ([#1269](https://github.com/alloy-rs/alloy/issues/1269)) + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Bug Fixes @@ -17,6 +46,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.3 - Require destination for 7702 ([#1262](https://github.com/alloy-rs/alloy/issues/1262)) - Swap BlockNumHash alias and struct name ([#1265](https://github.com/alloy-rs/alloy/issues/1265)) diff --git a/Cargo.toml b/Cargo.toml index c2bb401ac19..9ca2b11a744 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = ["crates/*"] resolver = "2" [workspace.package] -version = "0.3.3" +version = "0.3.4" edition = "2021" rust-version = "1.79" authors = ["Alloy Contributors"] diff --git a/crates/alloy/CHANGELOG.md b/crates/alloy/CHANGELOG.md index 8ca92dfdd18..a2967181097 100644 --- a/crates/alloy/CHANGELOG.md +++ b/crates/alloy/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Miscellaneous Tasks diff --git a/crates/consensus/CHANGELOG.md b/crates/consensus/CHANGELOG.md index 44727c60c6a..f1e08b442d3 100644 --- a/crates/consensus/CHANGELOG.md +++ b/crates/consensus/CHANGELOG.md @@ -5,10 +5,22 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Miscellaneous Tasks + +- [consensus] Remove Header Method ([#1271](https://github.com/alloy-rs/alloy/issues/1271)) +- [consensus] Alloc by Default ([#1272](https://github.com/alloy-rs/alloy/issues/1272)) + +### Other + +- Implement `seal` helper for `Header` ([#1269](https://github.com/alloy-rs/alloy/issues/1269)) + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks +- Release 0.3.3 - Require destination for 7702 ([#1262](https://github.com/alloy-rs/alloy/issues/1262)) ### Other diff --git a/crates/contract/CHANGELOG.md b/crates/contract/CHANGELOG.md index 870071431f2..4687c5828e6 100644 --- a/crates/contract/CHANGELOG.md +++ b/crates/contract/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Features + +- [alloy-rpc-types-eth] Optional serde ([#1276](https://github.com/alloy-rs/alloy/issues/1276)) + +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Miscellaneous Tasks diff --git a/crates/eip7547/CHANGELOG.md b/crates/eip7547/CHANGELOG.md index ccfb3e6e671..3d8b71a9481 100644 --- a/crates/eip7547/CHANGELOG.md +++ b/crates/eip7547/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Features + +- [engine] Optional Serde ([#1283](https://github.com/alloy-rs/alloy/issues/1283)) + +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Miscellaneous Tasks diff --git a/crates/eips/CHANGELOG.md b/crates/eips/CHANGELOG.md index 87273665698..bcc66cca988 100644 --- a/crates/eips/CHANGELOG.md +++ b/crates/eips/CHANGELOG.md @@ -5,10 +5,21 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Features + +- Add serde for NumHash ([#1277](https://github.com/alloy-rs/alloy/issues/1277)) + +### Miscellaneous Tasks + +- Swap `BlockHashOrNumber` alias and struct name ([#1270](https://github.com/alloy-rs/alloy/issues/1270)) + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks +- Release 0.3.3 - Swap BlockNumHash alias and struct name ([#1265](https://github.com/alloy-rs/alloy/issues/1265)) ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 diff --git a/crates/genesis/CHANGELOG.md b/crates/genesis/CHANGELOG.md index 0edc493fc42..98991cf32cb 100644 --- a/crates/genesis/CHANGELOG.md +++ b/crates/genesis/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Miscellaneous Tasks diff --git a/crates/json-rpc/CHANGELOG.md b/crates/json-rpc/CHANGELOG.md index 68c637a1e41..8de346ad557 100644 --- a/crates/json-rpc/CHANGELOG.md +++ b/crates/json-rpc/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Miscellaneous Tasks diff --git a/crates/network-primitives/CHANGELOG.md b/crates/network-primitives/CHANGELOG.md index 3137d71f4c0..e74afc960cc 100644 --- a/crates/network-primitives/CHANGELOG.md +++ b/crates/network-primitives/CHANGELOG.md @@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Miscellaneous Tasks + +- [network-primitives] Remove alloc Vec Dep ([#1267](https://github.com/alloy-rs/alloy/issues/1267)) + +### Other + +- Add trait methods `cumulative_gas_used` and `state_root` to `ReceiptResponse` ([#1275](https://github.com/alloy-rs/alloy/issues/1275)) + +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Features diff --git a/crates/network/CHANGELOG.md b/crates/network/CHANGELOG.md index 1ef0332c8cc..e4bc97197c4 100644 --- a/crates/network/CHANGELOG.md +++ b/crates/network/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Features + +- [alloy-rpc-types-eth] Optional serde ([#1276](https://github.com/alloy-rs/alloy/issues/1276)) + +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Miscellaneous Tasks diff --git a/crates/node-bindings/CHANGELOG.md b/crates/node-bindings/CHANGELOG.md index 656c9ad6af0..a56a77cc446 100644 --- a/crates/node-bindings/CHANGELOG.md +++ b/crates/node-bindings/CHANGELOG.md @@ -5,8 +5,22 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Bug Fixes + +- `debug_traceCallMany` and `trace_callMany` ([#1278](https://github.com/alloy-rs/alloy/issues/1278)) + +### Features + +- Improve node bindings ([#1279](https://github.com/alloy-rs/alloy/issues/1279)) + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 +### Miscellaneous Tasks + +- Release 0.3.3 + ### Testing - Dont use fork test ([#1263](https://github.com/alloy-rs/alloy/issues/1263)) diff --git a/crates/provider/CHANGELOG.md b/crates/provider/CHANGELOG.md index ec09db707ae..98e58d5da9a 100644 --- a/crates/provider/CHANGELOG.md +++ b/crates/provider/CHANGELOG.md @@ -5,6 +5,25 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Bug Fixes + +- `debug_traceCallMany` and `trace_callMany` ([#1278](https://github.com/alloy-rs/alloy/issues/1278)) +- Serde for `eth_simulateV1` ([#1273](https://github.com/alloy-rs/alloy/issues/1273)) + +### Features + +- [engine] Optional Serde ([#1283](https://github.com/alloy-rs/alloy/issues/1283)) +- [alloy-rpc-types-eth] Optional serde ([#1276](https://github.com/alloy-rs/alloy/issues/1276)) +- Improve node bindings ([#1279](https://github.com/alloy-rs/alloy/issues/1279)) + +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Miscellaneous Tasks diff --git a/crates/pubsub/CHANGELOG.md b/crates/pubsub/CHANGELOG.md index 30c35e4ab33..909bbd8c3a5 100644 --- a/crates/pubsub/CHANGELOG.md +++ b/crates/pubsub/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Miscellaneous Tasks diff --git a/crates/rpc-client/CHANGELOG.md b/crates/rpc-client/CHANGELOG.md index de093c010a4..1d640308a96 100644 --- a/crates/rpc-client/CHANGELOG.md +++ b/crates/rpc-client/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Features + +- Improve node bindings ([#1279](https://github.com/alloy-rs/alloy/issues/1279)) + +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Dependencies diff --git a/crates/rpc-types-admin/CHANGELOG.md b/crates/rpc-types-admin/CHANGELOG.md index e40713a2f82..3c436521d6f 100644 --- a/crates/rpc-types-admin/CHANGELOG.md +++ b/crates/rpc-types-admin/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Miscellaneous Tasks diff --git a/crates/rpc-types-anvil/CHANGELOG.md b/crates/rpc-types-anvil/CHANGELOG.md index 30d7a7cb211..bd5cd7dc08a 100644 --- a/crates/rpc-types-anvil/CHANGELOG.md +++ b/crates/rpc-types-anvil/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Miscellaneous Tasks diff --git a/crates/rpc-types-beacon/CHANGELOG.md b/crates/rpc-types-beacon/CHANGELOG.md index 05b74f0e163..502ecb5b151 100644 --- a/crates/rpc-types-beacon/CHANGELOG.md +++ b/crates/rpc-types-beacon/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Features + +- [engine] Optional Serde ([#1283](https://github.com/alloy-rs/alloy/issues/1283)) + +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Miscellaneous Tasks diff --git a/crates/rpc-types-debug/CHANGELOG.md b/crates/rpc-types-debug/CHANGELOG.md index e1b76917f12..17fb9ae2eb2 100644 --- a/crates/rpc-types-debug/CHANGELOG.md +++ b/crates/rpc-types-debug/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Miscellaneous Tasks diff --git a/crates/rpc-types-engine/CHANGELOG.md b/crates/rpc-types-engine/CHANGELOG.md index 39cfd483a77..f579ca581c5 100644 --- a/crates/rpc-types-engine/CHANGELOG.md +++ b/crates/rpc-types-engine/CHANGELOG.md @@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Features + +- [engine] Optional Serde ([#1283](https://github.com/alloy-rs/alloy/issues/1283)) +- [engine] No_std engine types ([#1268](https://github.com/alloy-rs/alloy/issues/1268)) + +### Miscellaneous Tasks + +- Remove eth rpc types dep from engine types ([#1280](https://github.com/alloy-rs/alloy/issues/1280)) + +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Features diff --git a/crates/rpc-types-eth/CHANGELOG.md b/crates/rpc-types-eth/CHANGELOG.md index 91abad35d20..3ccb356dad0 100644 --- a/crates/rpc-types-eth/CHANGELOG.md +++ b/crates/rpc-types-eth/CHANGELOG.md @@ -5,10 +5,27 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Bug Fixes + +- `debug_traceCallMany` and `trace_callMany` ([#1278](https://github.com/alloy-rs/alloy/issues/1278)) +- Serde for `eth_simulateV1` ([#1273](https://github.com/alloy-rs/alloy/issues/1273)) + +### Features + +- [alloy-rpc-types-eth] Optional serde ([#1276](https://github.com/alloy-rs/alloy/issues/1276)) +- No_std eth rpc types ([#1252](https://github.com/alloy-rs/alloy/issues/1252)) + +### Other + +- Add trait methods `cumulative_gas_used` and `state_root` to `ReceiptResponse` ([#1275](https://github.com/alloy-rs/alloy/issues/1275)) + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks +- Release 0.3.3 - Require destination for 7702 ([#1262](https://github.com/alloy-rs/alloy/issues/1262)) ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 diff --git a/crates/rpc-types-mev/CHANGELOG.md b/crates/rpc-types-mev/CHANGELOG.md index 9155ac895a6..45ad22f7c9c 100644 --- a/crates/rpc-types-mev/CHANGELOG.md +++ b/crates/rpc-types-mev/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Miscellaneous Tasks diff --git a/crates/rpc-types-trace/CHANGELOG.md b/crates/rpc-types-trace/CHANGELOG.md index 9c973121fa3..7ba4cea03f6 100644 --- a/crates/rpc-types-trace/CHANGELOG.md +++ b/crates/rpc-types-trace/CHANGELOG.md @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Features + +- [alloy-rpc-types-eth] Optional serde ([#1276](https://github.com/alloy-rs/alloy/issues/1276)) +- No_std eth rpc types ([#1252](https://github.com/alloy-rs/alloy/issues/1252)) + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Bug Fixes @@ -15,6 +22,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [rpc-types-trace] Always serialize result if no error ([#1258](https://github.com/alloy-rs/alloy/issues/1258)) +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Miscellaneous Tasks diff --git a/crates/rpc-types-txpool/CHANGELOG.md b/crates/rpc-types-txpool/CHANGELOG.md index 34804304166..2d9f5c6eaba 100644 --- a/crates/rpc-types-txpool/CHANGELOG.md +++ b/crates/rpc-types-txpool/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Miscellaneous Tasks diff --git a/crates/rpc-types/CHANGELOG.md b/crates/rpc-types/CHANGELOG.md index 3712b7274a8..28e89c72a20 100644 --- a/crates/rpc-types/CHANGELOG.md +++ b/crates/rpc-types/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Features + +- No_std eth rpc types ([#1252](https://github.com/alloy-rs/alloy/issues/1252)) + +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Miscellaneous Tasks diff --git a/crates/serde/CHANGELOG.md b/crates/serde/CHANGELOG.md index 1c4ea73de15..0c2bb6d51bc 100644 --- a/crates/serde/CHANGELOG.md +++ b/crates/serde/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Miscellaneous Tasks diff --git a/crates/signer-aws/CHANGELOG.md b/crates/signer-aws/CHANGELOG.md index 425f689aa40..4613782b02c 100644 --- a/crates/signer-aws/CHANGELOG.md +++ b/crates/signer-aws/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Miscellaneous Tasks diff --git a/crates/signer-gcp/CHANGELOG.md b/crates/signer-gcp/CHANGELOG.md index f4fbcb20723..00bea346404 100644 --- a/crates/signer-gcp/CHANGELOG.md +++ b/crates/signer-gcp/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Miscellaneous Tasks diff --git a/crates/signer-ledger/CHANGELOG.md b/crates/signer-ledger/CHANGELOG.md index ff9c08f2d01..520c956a82b 100644 --- a/crates/signer-ledger/CHANGELOG.md +++ b/crates/signer-ledger/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Miscellaneous Tasks diff --git a/crates/signer-local/CHANGELOG.md b/crates/signer-local/CHANGELOG.md index 1f750484ca2..5388558ffa3 100644 --- a/crates/signer-local/CHANGELOG.md +++ b/crates/signer-local/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Miscellaneous Tasks diff --git a/crates/signer-trezor/CHANGELOG.md b/crates/signer-trezor/CHANGELOG.md index caf1d6ec28f..878d2bb2677 100644 --- a/crates/signer-trezor/CHANGELOG.md +++ b/crates/signer-trezor/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Features + +- [alloy-rpc-types-eth] Optional serde ([#1276](https://github.com/alloy-rs/alloy/issues/1276)) + +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Miscellaneous Tasks diff --git a/crates/signer/CHANGELOG.md b/crates/signer/CHANGELOG.md index 86526cebe52..8b978a1dea6 100644 --- a/crates/signer/CHANGELOG.md +++ b/crates/signer/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Miscellaneous Tasks diff --git a/crates/transport-http/CHANGELOG.md b/crates/transport-http/CHANGELOG.md index a6adeaf56a4..dbd49d3b262 100644 --- a/crates/transport-http/CHANGELOG.md +++ b/crates/transport-http/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Miscellaneous Tasks diff --git a/crates/transport-ipc/CHANGELOG.md b/crates/transport-ipc/CHANGELOG.md index d9769994646..53c504ca5fc 100644 --- a/crates/transport-ipc/CHANGELOG.md +++ b/crates/transport-ipc/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Miscellaneous Tasks diff --git a/crates/transport-ws/CHANGELOG.md b/crates/transport-ws/CHANGELOG.md index 86935a70de6..729f7a404b7 100644 --- a/crates/transport-ws/CHANGELOG.md +++ b/crates/transport-ws/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Miscellaneous Tasks diff --git a/crates/transport/CHANGELOG.md b/crates/transport/CHANGELOG.md index 9bf42aaafb7..c2e71fb155e 100644 --- a/crates/transport/CHANGELOG.md +++ b/crates/transport/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 + +### Miscellaneous Tasks + +- Release 0.3.3 + ## [0.3.2](https://github.com/alloy-rs/alloy/releases/tag/v0.3.2) - 2024-09-09 ### Miscellaneous Tasks From 6ea2451645c75b7f7e47efb552fccfc577de5a4b Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Fri, 13 Sep 2024 17:19:37 +0200 Subject: [PATCH 170/186] fix: add missing conversion (#1287) --- crates/rpc-types-engine/src/payload.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crates/rpc-types-engine/src/payload.rs b/crates/rpc-types-engine/src/payload.rs index ba33c8dd51a..1d35a261594 100644 --- a/crates/rpc-types-engine/src/payload.rs +++ b/crates/rpc-types-engine/src/payload.rs @@ -862,6 +862,12 @@ impl std::error::Error for PayloadError { } } +impl From for PayloadError { + fn from(value: alloy_rlp::Error) -> Self { + Self::Decode(value) + } +} + impl PayloadError { /// Returns `true` if the error is caused by a block hash mismatch. #[inline] From ba29d6b7307da9951126dcaba27829e17443b680 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Fri, 13 Sep 2024 17:20:59 +0200 Subject: [PATCH 171/186] chore: release 0.3.5 --- CHANGELOG.md | 7 +++++++ Cargo.toml | 2 +- crates/alloy/CHANGELOG.md | 6 ++++++ crates/consensus/CHANGELOG.md | 1 + crates/contract/CHANGELOG.md | 4 ++++ crates/eip7547/CHANGELOG.md | 4 ++++ crates/eips/CHANGELOG.md | 1 + crates/genesis/CHANGELOG.md | 6 ++++++ crates/json-rpc/CHANGELOG.md | 6 ++++++ crates/network-primitives/CHANGELOG.md | 1 + crates/network/CHANGELOG.md | 4 ++++ crates/node-bindings/CHANGELOG.md | 4 ++++ crates/provider/CHANGELOG.md | 4 ++++ crates/pubsub/CHANGELOG.md | 6 ++++++ crates/rpc-client/CHANGELOG.md | 4 ++++ crates/rpc-types-admin/CHANGELOG.md | 6 ++++++ crates/rpc-types-anvil/CHANGELOG.md | 6 ++++++ crates/rpc-types-beacon/CHANGELOG.md | 4 ++++ crates/rpc-types-debug/CHANGELOG.md | 6 ++++++ crates/rpc-types-engine/CHANGELOG.md | 7 +++++++ crates/rpc-types-eth/CHANGELOG.md | 4 ++++ crates/rpc-types-mev/CHANGELOG.md | 6 ++++++ crates/rpc-types-trace/CHANGELOG.md | 4 ++++ crates/rpc-types-txpool/CHANGELOG.md | 6 ++++++ crates/rpc-types/CHANGELOG.md | 4 ++++ crates/serde/CHANGELOG.md | 6 ++++++ crates/signer-aws/CHANGELOG.md | 6 ++++++ crates/signer-gcp/CHANGELOG.md | 6 ++++++ crates/signer-ledger/CHANGELOG.md | 6 ++++++ crates/signer-local/CHANGELOG.md | 6 ++++++ crates/signer-trezor/CHANGELOG.md | 4 ++++ crates/signer/CHANGELOG.md | 6 ++++++ crates/transport-http/CHANGELOG.md | 6 ++++++ crates/transport-ipc/CHANGELOG.md | 6 ++++++ crates/transport-ws/CHANGELOG.md | 6 ++++++ crates/transport/CHANGELOG.md | 6 ++++++ 36 files changed, 176 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index abe75d70677..cf3954877c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.5](https://github.com/alloy-rs/alloy/releases/tag/v0.3.5) - 2024-09-13 + +### Bug Fixes + +- Add missing conversion ([#1287](https://github.com/alloy-rs/alloy/issues/1287)) + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Bug Fixes @@ -23,6 +29,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.4 - Remove eth rpc types dep from engine types ([#1280](https://github.com/alloy-rs/alloy/issues/1280)) - Swap `BlockHashOrNumber` alias and struct name ([#1270](https://github.com/alloy-rs/alloy/issues/1270)) - [consensus] Remove Header Method ([#1271](https://github.com/alloy-rs/alloy/issues/1271)) diff --git a/Cargo.toml b/Cargo.toml index 9ca2b11a744..9290524cab8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = ["crates/*"] resolver = "2" [workspace.package] -version = "0.3.4" +version = "0.3.5" edition = "2021" rust-version = "1.79" authors = ["Alloy Contributors"] diff --git a/crates/alloy/CHANGELOG.md b/crates/alloy/CHANGELOG.md index a2967181097..de6919bcc8b 100644 --- a/crates/alloy/CHANGELOG.md +++ b/crates/alloy/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks diff --git a/crates/consensus/CHANGELOG.md b/crates/consensus/CHANGELOG.md index f1e08b442d3..2d5e73b6bf8 100644 --- a/crates/consensus/CHANGELOG.md +++ b/crates/consensus/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.4 - [consensus] Remove Header Method ([#1271](https://github.com/alloy-rs/alloy/issues/1271)) - [consensus] Alloc by Default ([#1272](https://github.com/alloy-rs/alloy/issues/1272)) diff --git a/crates/contract/CHANGELOG.md b/crates/contract/CHANGELOG.md index 4687c5828e6..523d84d6a30 100644 --- a/crates/contract/CHANGELOG.md +++ b/crates/contract/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [alloy-rpc-types-eth] Optional serde ([#1276](https://github.com/alloy-rs/alloy/issues/1276)) +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks diff --git a/crates/eip7547/CHANGELOG.md b/crates/eip7547/CHANGELOG.md index 3d8b71a9481..0ce1a83510e 100644 --- a/crates/eip7547/CHANGELOG.md +++ b/crates/eip7547/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [engine] Optional Serde ([#1283](https://github.com/alloy-rs/alloy/issues/1283)) +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks diff --git a/crates/eips/CHANGELOG.md b/crates/eips/CHANGELOG.md index bcc66cca988..96461adab81 100644 --- a/crates/eips/CHANGELOG.md +++ b/crates/eips/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.4 - Swap `BlockHashOrNumber` alias and struct name ([#1270](https://github.com/alloy-rs/alloy/issues/1270)) ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 diff --git a/crates/genesis/CHANGELOG.md b/crates/genesis/CHANGELOG.md index 98991cf32cb..d7bbdbfac44 100644 --- a/crates/genesis/CHANGELOG.md +++ b/crates/genesis/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks diff --git a/crates/json-rpc/CHANGELOG.md b/crates/json-rpc/CHANGELOG.md index 8de346ad557..263d113a689 100644 --- a/crates/json-rpc/CHANGELOG.md +++ b/crates/json-rpc/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks diff --git a/crates/network-primitives/CHANGELOG.md b/crates/network-primitives/CHANGELOG.md index e74afc960cc..286bdd412b0 100644 --- a/crates/network-primitives/CHANGELOG.md +++ b/crates/network-primitives/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.4 - [network-primitives] Remove alloc Vec Dep ([#1267](https://github.com/alloy-rs/alloy/issues/1267)) ### Other diff --git a/crates/network/CHANGELOG.md b/crates/network/CHANGELOG.md index e4bc97197c4..22b42794f8d 100644 --- a/crates/network/CHANGELOG.md +++ b/crates/network/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [alloy-rpc-types-eth] Optional serde ([#1276](https://github.com/alloy-rs/alloy/issues/1276)) +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks diff --git a/crates/node-bindings/CHANGELOG.md b/crates/node-bindings/CHANGELOG.md index a56a77cc446..ebddc954e38 100644 --- a/crates/node-bindings/CHANGELOG.md +++ b/crates/node-bindings/CHANGELOG.md @@ -15,6 +15,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Improve node bindings ([#1279](https://github.com/alloy-rs/alloy/issues/1279)) +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks diff --git a/crates/provider/CHANGELOG.md b/crates/provider/CHANGELOG.md index 98e58d5da9a..287875911a5 100644 --- a/crates/provider/CHANGELOG.md +++ b/crates/provider/CHANGELOG.md @@ -18,6 +18,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [alloy-rpc-types-eth] Optional serde ([#1276](https://github.com/alloy-rs/alloy/issues/1276)) - Improve node bindings ([#1279](https://github.com/alloy-rs/alloy/issues/1279)) +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks diff --git a/crates/pubsub/CHANGELOG.md b/crates/pubsub/CHANGELOG.md index 909bbd8c3a5..216c6c6f050 100644 --- a/crates/pubsub/CHANGELOG.md +++ b/crates/pubsub/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks diff --git a/crates/rpc-client/CHANGELOG.md b/crates/rpc-client/CHANGELOG.md index 1d640308a96..aa47395b369 100644 --- a/crates/rpc-client/CHANGELOG.md +++ b/crates/rpc-client/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Improve node bindings ([#1279](https://github.com/alloy-rs/alloy/issues/1279)) +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks diff --git a/crates/rpc-types-admin/CHANGELOG.md b/crates/rpc-types-admin/CHANGELOG.md index 3c436521d6f..3076665f832 100644 --- a/crates/rpc-types-admin/CHANGELOG.md +++ b/crates/rpc-types-admin/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks diff --git a/crates/rpc-types-anvil/CHANGELOG.md b/crates/rpc-types-anvil/CHANGELOG.md index bd5cd7dc08a..2df6e5bee3d 100644 --- a/crates/rpc-types-anvil/CHANGELOG.md +++ b/crates/rpc-types-anvil/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks diff --git a/crates/rpc-types-beacon/CHANGELOG.md b/crates/rpc-types-beacon/CHANGELOG.md index 502ecb5b151..86dedc29830 100644 --- a/crates/rpc-types-beacon/CHANGELOG.md +++ b/crates/rpc-types-beacon/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [engine] Optional Serde ([#1283](https://github.com/alloy-rs/alloy/issues/1283)) +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks diff --git a/crates/rpc-types-debug/CHANGELOG.md b/crates/rpc-types-debug/CHANGELOG.md index 17fb9ae2eb2..fcc5e267023 100644 --- a/crates/rpc-types-debug/CHANGELOG.md +++ b/crates/rpc-types-debug/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks diff --git a/crates/rpc-types-engine/CHANGELOG.md b/crates/rpc-types-engine/CHANGELOG.md index f579ca581c5..ea5b9aece2e 100644 --- a/crates/rpc-types-engine/CHANGELOG.md +++ b/crates/rpc-types-engine/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.5](https://github.com/alloy-rs/alloy/releases/tag/v0.3.5) - 2024-09-13 + +### Bug Fixes + +- Add missing conversion ([#1287](https://github.com/alloy-rs/alloy/issues/1287)) + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Features @@ -14,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.4 - Remove eth rpc types dep from engine types ([#1280](https://github.com/alloy-rs/alloy/issues/1280)) ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 diff --git a/crates/rpc-types-eth/CHANGELOG.md b/crates/rpc-types-eth/CHANGELOG.md index 3ccb356dad0..18ef35d55ba 100644 --- a/crates/rpc-types-eth/CHANGELOG.md +++ b/crates/rpc-types-eth/CHANGELOG.md @@ -17,6 +17,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [alloy-rpc-types-eth] Optional serde ([#1276](https://github.com/alloy-rs/alloy/issues/1276)) - No_std eth rpc types ([#1252](https://github.com/alloy-rs/alloy/issues/1252)) +### Miscellaneous Tasks + +- Release 0.3.4 + ### Other - Add trait methods `cumulative_gas_used` and `state_root` to `ReceiptResponse` ([#1275](https://github.com/alloy-rs/alloy/issues/1275)) diff --git a/crates/rpc-types-mev/CHANGELOG.md b/crates/rpc-types-mev/CHANGELOG.md index 45ad22f7c9c..a55d730f02c 100644 --- a/crates/rpc-types-mev/CHANGELOG.md +++ b/crates/rpc-types-mev/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks diff --git a/crates/rpc-types-trace/CHANGELOG.md b/crates/rpc-types-trace/CHANGELOG.md index 7ba4cea03f6..b56ddeea590 100644 --- a/crates/rpc-types-trace/CHANGELOG.md +++ b/crates/rpc-types-trace/CHANGELOG.md @@ -12,6 +12,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [alloy-rpc-types-eth] Optional serde ([#1276](https://github.com/alloy-rs/alloy/issues/1276)) - No_std eth rpc types ([#1252](https://github.com/alloy-rs/alloy/issues/1252)) +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Bug Fixes diff --git a/crates/rpc-types-txpool/CHANGELOG.md b/crates/rpc-types-txpool/CHANGELOG.md index 2d9f5c6eaba..fca344e0a8e 100644 --- a/crates/rpc-types-txpool/CHANGELOG.md +++ b/crates/rpc-types-txpool/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks diff --git a/crates/rpc-types/CHANGELOG.md b/crates/rpc-types/CHANGELOG.md index 28e89c72a20..19af1f7f415 100644 --- a/crates/rpc-types/CHANGELOG.md +++ b/crates/rpc-types/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - No_std eth rpc types ([#1252](https://github.com/alloy-rs/alloy/issues/1252)) +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks diff --git a/crates/serde/CHANGELOG.md b/crates/serde/CHANGELOG.md index 0c2bb6d51bc..c3367e2c79a 100644 --- a/crates/serde/CHANGELOG.md +++ b/crates/serde/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks diff --git a/crates/signer-aws/CHANGELOG.md b/crates/signer-aws/CHANGELOG.md index 4613782b02c..8dd96fd3ab9 100644 --- a/crates/signer-aws/CHANGELOG.md +++ b/crates/signer-aws/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks diff --git a/crates/signer-gcp/CHANGELOG.md b/crates/signer-gcp/CHANGELOG.md index 00bea346404..add89ebf3e4 100644 --- a/crates/signer-gcp/CHANGELOG.md +++ b/crates/signer-gcp/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks diff --git a/crates/signer-ledger/CHANGELOG.md b/crates/signer-ledger/CHANGELOG.md index 520c956a82b..02b698dab13 100644 --- a/crates/signer-ledger/CHANGELOG.md +++ b/crates/signer-ledger/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks diff --git a/crates/signer-local/CHANGELOG.md b/crates/signer-local/CHANGELOG.md index 5388558ffa3..044fa381973 100644 --- a/crates/signer-local/CHANGELOG.md +++ b/crates/signer-local/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks diff --git a/crates/signer-trezor/CHANGELOG.md b/crates/signer-trezor/CHANGELOG.md index 878d2bb2677..e3509906c92 100644 --- a/crates/signer-trezor/CHANGELOG.md +++ b/crates/signer-trezor/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [alloy-rpc-types-eth] Optional serde ([#1276](https://github.com/alloy-rs/alloy/issues/1276)) +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks diff --git a/crates/signer/CHANGELOG.md b/crates/signer/CHANGELOG.md index 8b978a1dea6..fb351d68f2f 100644 --- a/crates/signer/CHANGELOG.md +++ b/crates/signer/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks diff --git a/crates/transport-http/CHANGELOG.md b/crates/transport-http/CHANGELOG.md index dbd49d3b262..f8f7eaeb128 100644 --- a/crates/transport-http/CHANGELOG.md +++ b/crates/transport-http/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks diff --git a/crates/transport-ipc/CHANGELOG.md b/crates/transport-ipc/CHANGELOG.md index 53c504ca5fc..f5c8afe2449 100644 --- a/crates/transport-ipc/CHANGELOG.md +++ b/crates/transport-ipc/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks diff --git a/crates/transport-ws/CHANGELOG.md b/crates/transport-ws/CHANGELOG.md index 729f7a404b7..55b0f4b8847 100644 --- a/crates/transport-ws/CHANGELOG.md +++ b/crates/transport-ws/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks diff --git a/crates/transport/CHANGELOG.md b/crates/transport/CHANGELOG.md index c2e71fb155e..f6207061d43 100644 --- a/crates/transport/CHANGELOG.md +++ b/crates/transport/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.4 + ## [0.3.3](https://github.com/alloy-rs/alloy/releases/tag/v0.3.3) - 2024-09-10 ### Miscellaneous Tasks From de77456fa3e3b5d47fd58dcc9e90824d11cbe58e Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Fri, 13 Sep 2024 17:39:41 +0200 Subject: [PATCH 172/186] chore: release 0.3.5 --- CHANGELOG.md | 4 ++++ crates/alloy/CHANGELOG.md | 6 ++++++ crates/eip7547/CHANGELOG.md | 6 ++++++ 3 files changed, 16 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf3954877c3..cc1ebcf40b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add missing conversion ([#1287](https://github.com/alloy-rs/alloy/issues/1287)) +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Bug Fixes diff --git a/crates/alloy/CHANGELOG.md b/crates/alloy/CHANGELOG.md index de6919bcc8b..90a83338b4e 100644 --- a/crates/alloy/CHANGELOG.md +++ b/crates/alloy/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.5](https://github.com/alloy-rs/alloy/releases/tag/v0.3.5) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Miscellaneous Tasks diff --git a/crates/eip7547/CHANGELOG.md b/crates/eip7547/CHANGELOG.md index 0ce1a83510e..6e08a67ddc6 100644 --- a/crates/eip7547/CHANGELOG.md +++ b/crates/eip7547/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.5](https://github.com/alloy-rs/alloy/releases/tag/v0.3.5) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Features From cbfe3d9111337b5d1d59e01d4b6d541335da4889 Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Sat, 14 Sep 2024 07:11:35 +0400 Subject: [PATCH 173/186] fix: `eth_simulateV1` (#1289) * fix * add aliases * cfg_attr --- crates/rpc-types-eth/src/block.rs | 15 ++++++++++++--- crates/rpc-types-eth/src/simulate.rs | 1 + 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/crates/rpc-types-eth/src/block.rs b/crates/rpc-types-eth/src/block.rs index 83f9790e6d9..35e9a1730fa 100644 --- a/crates/rpc-types-eth/src/block.rs +++ b/crates/rpc-types-eth/src/block.rs @@ -347,13 +347,22 @@ pub struct BlockOverrides { )] pub gas_limit: Option, /// Overrides the coinbase address of the block. - #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] + #[cfg_attr( + feature = "serde", + serde(default, skip_serializing_if = "Option::is_none", alias = "feeRecipient") + )] pub coinbase: Option
, /// Overrides the prevrandao of the block. - #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] + #[cfg_attr( + feature = "serde", + serde(default, skip_serializing_if = "Option::is_none", alias = "prevRandao") + )] pub random: Option, /// Overrides the basefee of the block. - #[cfg_attr(feature = "serde", serde(default, skip_serializing_if = "Option::is_none"))] + #[cfg_attr( + feature = "serde", + serde(default, skip_serializing_if = "Option::is_none", alias = "baseFeePerGas") + )] pub base_fee: Option, /// A dictionary that maps blockNumber to a user-defined hash. It could be queried from the /// solidity opcode BLOCKHASH. diff --git a/crates/rpc-types-eth/src/simulate.rs b/crates/rpc-types-eth/src/simulate.rs index 42247519229..798f2ac0870 100644 --- a/crates/rpc-types-eth/src/simulate.rs +++ b/crates/rpc-types-eth/src/simulate.rs @@ -75,6 +75,7 @@ pub struct SimulatePayload { #[cfg_attr(feature = "serde", serde(default))] pub validation: bool, /// Flag to decide if full transactions should be returned instead of just their hashes. + #[cfg_attr(feature = "serde", serde(default))] pub return_full_transactions: bool, } From cb81345309c92a0a621f5f3a50a8a667dca6fca1 Mon Sep 17 00:00:00 2001 From: refcell Date: Mon, 16 Sep 2024 22:50:43 -0400 Subject: [PATCH 174/186] chore(engine): `no_std` Checks (#1298) --- scripts/check_no_std.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/check_no_std.sh b/scripts/check_no_std.sh index dd2f00262e0..62ebbd5d426 100755 --- a/scripts/check_no_std.sh +++ b/scripts/check_no_std.sh @@ -9,6 +9,7 @@ crates=( alloy-consensus alloy-network-primitives alloy-rpc-types-eth + alloy-rpc-types-engine ) cmd=(cargo +stable hack check --no-default-features --target "$target") From 4e8f429572ddd4f8bb58cf8a7acaebc75c609b2c Mon Sep 17 00:00:00 2001 From: refcell Date: Tue, 17 Sep 2024 05:33:48 -0400 Subject: [PATCH 175/186] fix(types-eth): Optional Alloy Serde (#1284) * feat: optional serde * feat: optional serde * fix: tests * fix: enable serde for alloy-rpc-types-trace * fix: non-attr serde * feat: optional alloy-serde --- crates/rpc-types-eth/Cargo.toml | 4 ++-- crates/rpc-types-eth/src/account.rs | 5 +++-- crates/rpc-types-eth/src/block.rs | 12 +++++++----- crates/rpc-types-eth/src/lib.rs | 3 +++ crates/rpc-types-eth/src/transaction/mod.rs | 5 ++++- crates/rpc-types-eth/src/transaction/receipt.rs | 5 +++-- 6 files changed, 22 insertions(+), 12 deletions(-) diff --git a/crates/rpc-types-eth/Cargo.toml b/crates/rpc-types-eth/Cargo.toml index 14ac0ee0b2b..cad5e6a788b 100644 --- a/crates/rpc-types-eth/Cargo.toml +++ b/crates/rpc-types-eth/Cargo.toml @@ -20,7 +20,6 @@ workspace = true [dependencies] alloy-eips.workspace = true -alloy-serde.workspace = true alloy-consensus.workspace = true alloy-network-primitives.workspace = true alloy-rlp = { workspace = true, features = ["arrayvec", "derive"] } @@ -30,6 +29,7 @@ itertools.workspace = true derive_more = { workspace = true, features = ["display"] } # serde +alloy-serde = { workspace = true, optional = true } serde = { workspace = true, features = ["derive"], optional = true } serde_json = { workspace = true, optional = true } @@ -62,7 +62,7 @@ assert_matches.workspace = true [features] default = ["std", "serde"] std = ["alloy-primitives/std", "alloy-consensus/std", "alloy-eips/std"] -serde = ["dep:serde", "dep:serde_json", "alloy-primitives/serde", "alloy-consensus/serde", "alloy-eips/serde"] +serde = ["dep:serde", "dep:serde_json", "dep:alloy-serde", "alloy-primitives/serde", "alloy-consensus/serde", "alloy-eips/serde"] arbitrary = [ "std", "dep:arbitrary", diff --git a/crates/rpc-types-eth/src/account.rs b/crates/rpc-types-eth/src/account.rs index 6e99bceceba..54e8651a39d 100644 --- a/crates/rpc-types-eth/src/account.rs +++ b/crates/rpc-types-eth/src/account.rs @@ -1,5 +1,4 @@ use alloy_primitives::{Address, Bytes, B256, B512, U256}; -use alloy_serde::storage::JsonStorageKey; use alloc::{string::String, vec::Vec}; @@ -16,11 +15,12 @@ pub struct AccountInfo { /// Data structure with proof for one single storage-entry #[derive(Clone, Debug, Default, PartialEq, Eq)] +#[cfg(feature = "serde")] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct EIP1186StorageProof { /// Storage key. - pub key: JsonStorageKey, + pub key: alloy_serde::storage::JsonStorageKey, /// Value that the key holds pub value: U256, /// proof for the pair @@ -29,6 +29,7 @@ pub struct EIP1186StorageProof { /// Response for EIP-1186 account proof `eth_getProof` #[derive(Clone, Debug, Default, PartialEq, Eq)] +#[cfg(feature = "serde")] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct EIP1186AccountProofResponse { diff --git a/crates/rpc-types-eth/src/block.rs b/crates/rpc-types-eth/src/block.rs index 35e9a1730fa..ef47e3f1a42 100644 --- a/crates/rpc-types-eth/src/block.rs +++ b/crates/rpc-types-eth/src/block.rs @@ -6,7 +6,6 @@ use alloy_network_primitives::{ BlockResponse, BlockTransactions, HeaderResponse, TransactionResponse, }; use alloy_primitives::{Address, BlockHash, Bloom, Bytes, B256, B64, U256}; -use alloy_serde::WithOtherFields; use alloc::vec::Vec; @@ -294,13 +293,15 @@ impl std::error::Error for BlockError { } } -impl From for WithOtherFields { +#[cfg(feature = "serde")] +impl From for alloy_serde::WithOtherFields { fn from(inner: Block) -> Self { Self { inner, other: Default::default() } } } -impl From
for WithOtherFields
{ +#[cfg(feature = "serde")] +impl From
for alloy_serde::WithOtherFields
{ fn from(inner: Header) -> Self { Self { inner, other: Default::default() } } @@ -577,9 +578,10 @@ mod tests { "size": "0xaeb6" }"#; - let block = serde_json::from_str::>(s).unwrap(); + let block = serde_json::from_str::>(s).unwrap(); let serialized = serde_json::to_string(&block).unwrap(); - let block2 = serde_json::from_str::>(&serialized).unwrap(); + let block2 = + serde_json::from_str::>(&serialized).unwrap(); assert_eq!(block, block2); } diff --git a/crates/rpc-types-eth/src/lib.rs b/crates/rpc-types-eth/src/lib.rs index c39a1a2c124..b8ab655726b 100644 --- a/crates/rpc-types-eth/src/lib.rs +++ b/crates/rpc-types-eth/src/lib.rs @@ -29,9 +29,11 @@ pub use account::*; mod block; pub use block::*; +#[cfg(feature = "serde")] use alloy_serde::WithOtherFields; /// A catch-all block type for handling blocks on multiple networks. +#[cfg(feature = "serde")] pub type AnyNetworkBlock = WithOtherFields>>; pub use alloy_network_primitives::{ @@ -55,6 +57,7 @@ pub use index::Index; mod log; pub use log::*; +#[cfg(feature = "serde")] pub mod pubsub; mod raw_log; diff --git a/crates/rpc-types-eth/src/transaction/mod.rs b/crates/rpc-types-eth/src/transaction/mod.rs index 19e30d1cf7d..824f942f143 100644 --- a/crates/rpc-types-eth/src/transaction/mod.rs +++ b/crates/rpc-types-eth/src/transaction/mod.rs @@ -23,7 +23,10 @@ mod error; pub use error::ConversionError; mod receipt; -pub use receipt::{AnyTransactionReceipt, TransactionReceipt}; +pub use receipt::TransactionReceipt; + +#[cfg(feature = "serde")] +pub use receipt::AnyTransactionReceipt; pub mod request; pub use request::{TransactionInput, TransactionRequest}; diff --git a/crates/rpc-types-eth/src/transaction/receipt.rs b/crates/rpc-types-eth/src/transaction/receipt.rs index 2901e888f1a..48353e6fba3 100644 --- a/crates/rpc-types-eth/src/transaction/receipt.rs +++ b/crates/rpc-types-eth/src/transaction/receipt.rs @@ -3,7 +3,6 @@ use alloy_consensus::{AnyReceiptEnvelope, ReceiptEnvelope, TxReceipt, TxType}; use alloy_eips::eip7702::SignedAuthorization; use alloy_network_primitives::ReceiptResponse; use alloy_primitives::{Address, BlockHash, TxHash, B256}; -use alloy_serde::WithOtherFields; use alloc::vec::Vec; @@ -144,7 +143,9 @@ impl TransactionReceipt { /// Alias for a catch-all receipt type. #[doc(alias = "AnyTxReceipt")] -pub type AnyTransactionReceipt = WithOtherFields>>; +#[cfg(feature = "serde")] +pub type AnyTransactionReceipt = + alloy_serde::WithOtherFields>>; impl> ReceiptResponse for TransactionReceipt { fn contract_address(&self) -> Option
{ From 099e64dbb462d3f5c04e9292ef306b10399694ad Mon Sep 17 00:00:00 2001 From: Arsenii Kulikov Date: Tue, 17 Sep 2024 14:30:24 +0300 Subject: [PATCH 176/186] refactor: separate transaction builders for tx types (#1259) * refactor: txtype-specific transaction builders * enforce legacy if access list * ignore access list --- crates/contract/src/call.rs | 12 +- crates/network/src/any/builder.rs | 54 ++++---- crates/network/src/ethereum/builder.rs | 61 +++++---- crates/network/src/lib.rs | 4 +- crates/network/src/transaction/builder.rs | 85 +++++++------ crates/network/src/transaction/mod.rs | 3 +- crates/provider/src/builder.rs | 11 +- crates/provider/src/fillers/gas.rs | 145 +++++++++------------- crates/provider/src/fillers/mod.rs | 43 ++++++- 9 files changed, 227 insertions(+), 191 deletions(-) diff --git a/crates/contract/src/call.rs b/crates/contract/src/call.rs index d9aaf5279ce..c7d164e6acb 100644 --- a/crates/contract/src/call.rs +++ b/crates/contract/src/call.rs @@ -1,7 +1,7 @@ use crate::{CallDecoder, Error, EthCall, Result}; use alloy_dyn_abi::{DynSolValue, JsonAbiExt}; use alloy_json_abi::Function; -use alloy_network::{Ethereum, Network, TransactionBuilder}; +use alloy_network::{Ethereum, Network, TransactionBuilder, TransactionBuilder4844}; use alloy_network_primitives::ReceiptResponse; use alloy_primitives::{Address, Bytes, ChainId, TxKind, U256}; use alloy_provider::{PendingTransactionBuilder, Provider}; @@ -334,7 +334,10 @@ impl, D: CallDecoder, N: Network> CallBu } /// Sets the `sidecar` field in the transaction to the provided value. - pub fn sidecar(mut self, blob_sidecar: BlobTransactionSidecar) -> Self { + pub fn sidecar(mut self, blob_sidecar: BlobTransactionSidecar) -> Self + where + N::TransactionRequest: TransactionBuilder4844, + { self.request.set_blob_sidecar(blob_sidecar); self } @@ -371,7 +374,10 @@ impl, D: CallDecoder, N: Network> CallBu } /// Sets the `max_fee_per_blob_gas` in the transaction to the provided value - pub fn max_fee_per_blob_gas(mut self, max_fee_per_blob_gas: u128) -> Self { + pub fn max_fee_per_blob_gas(mut self, max_fee_per_blob_gas: u128) -> Self + where + N::TransactionRequest: TransactionBuilder4844, + { self.request.set_max_fee_per_blob_gas(max_fee_per_blob_gas); self } diff --git a/crates/network/src/any/builder.rs b/crates/network/src/any/builder.rs index 66618489e00..2d53702eab3 100644 --- a/crates/network/src/any/builder.rs +++ b/crates/network/src/any/builder.rs @@ -1,6 +1,6 @@ use crate::{ any::AnyNetwork, BuildResult, Network, NetworkWallet, TransactionBuilder, - TransactionBuilderError, + TransactionBuilder4844, TransactionBuilder7702, TransactionBuilderError, }; use alloy_consensus::BlobTransactionSidecar; use alloy_eips::eip7702::SignedAuthorization; @@ -86,14 +86,6 @@ impl TransactionBuilder for WithOtherFields { 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: u128) { - self.deref_mut().set_max_fee_per_blob_gas(max_fee_per_blob_gas) - } - fn gas_limit(&self) -> Option { self.deref().gas_limit() } @@ -112,22 +104,6 @@ impl TransactionBuilder for WithOtherFields { self.deref_mut().set_access_list(access_list) } - fn blob_sidecar(&self) -> Option<&BlobTransactionSidecar> { - self.deref().blob_sidecar() - } - - fn set_blob_sidecar(&mut self, sidecar: BlobTransactionSidecar) { - self.deref_mut().set_blob_sidecar(sidecar) - } - - fn authorization_list(&self) -> Option<&Vec> { - self.deref().authorization_list() - } - - fn set_authorization_list(&mut self, authorization_list: Vec) { - self.deref_mut().set_authorization_list(authorization_list) - } - fn complete_type(&self, ty: ::TxType) -> Result<(), Vec<&'static str>> { self.deref().complete_type(ty.try_into().map_err(|_| vec!["supported tx type"])?) } @@ -172,3 +148,31 @@ impl TransactionBuilder for WithOtherFields { Ok(wallet.sign_request(self).await?) } } + +impl TransactionBuilder4844 for WithOtherFields { + 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: u128) { + self.deref_mut().set_max_fee_per_blob_gas(max_fee_per_blob_gas) + } + + fn blob_sidecar(&self) -> Option<&BlobTransactionSidecar> { + self.deref().blob_sidecar() + } + + fn set_blob_sidecar(&mut self, sidecar: BlobTransactionSidecar) { + self.deref_mut().set_blob_sidecar(sidecar) + } +} + +impl TransactionBuilder7702 for WithOtherFields { + fn authorization_list(&self) -> Option<&Vec> { + self.deref().authorization_list() + } + + fn set_authorization_list(&mut self, authorization_list: Vec) { + self.deref_mut().set_authorization_list(authorization_list) + } +} diff --git a/crates/network/src/ethereum/builder.rs b/crates/network/src/ethereum/builder.rs index e2328cca4c5..f4b90972e62 100644 --- a/crates/network/src/ethereum/builder.rs +++ b/crates/network/src/ethereum/builder.rs @@ -1,5 +1,6 @@ use crate::{ - BuildResult, Ethereum, Network, NetworkWallet, TransactionBuilder, TransactionBuilderError, + BuildResult, Ethereum, Network, NetworkWallet, TransactionBuilder, TransactionBuilder4844, + TransactionBuilder7702, TransactionBuilderError, }; use alloy_consensus::{BlobTransactionSidecar, TxType, TypedTransaction}; use alloy_eips::eip7702::SignedAuthorization; @@ -83,14 +84,6 @@ impl TransactionBuilder for TransactionRequest { self.max_priority_fee_per_gas = Some(max_priority_fee_per_gas); } - fn max_fee_per_blob_gas(&self) -> Option { - self.max_fee_per_blob_gas - } - - fn set_max_fee_per_blob_gas(&mut self, max_fee_per_blob_gas: u128) { - self.max_fee_per_blob_gas = Some(max_fee_per_blob_gas) - } - fn gas_limit(&self) -> Option { self.gas } @@ -107,23 +100,6 @@ impl TransactionBuilder for TransactionRequest { self.access_list = Some(access_list); } - fn blob_sidecar(&self) -> Option<&BlobTransactionSidecar> { - self.sidecar.as_ref() - } - - fn set_blob_sidecar(&mut self, sidecar: BlobTransactionSidecar) { - self.sidecar = Some(sidecar); - self.populate_blob_hashes(); - } - - fn authorization_list(&self) -> Option<&Vec> { - self.authorization_list.as_ref() - } - - fn set_authorization_list(&mut self, authorization_list: Vec) { - self.authorization_list = Some(authorization_list); - } - fn complete_type(&self, ty: TxType) -> Result<(), Vec<&'static str>> { match ty { TxType::Legacy => self.complete_legacy(), @@ -191,9 +167,40 @@ impl TransactionBuilder for TransactionRequest { } } +impl TransactionBuilder4844 for TransactionRequest { + fn max_fee_per_blob_gas(&self) -> Option { + self.max_fee_per_blob_gas + } + + fn set_max_fee_per_blob_gas(&mut self, max_fee_per_blob_gas: u128) { + self.max_fee_per_blob_gas = Some(max_fee_per_blob_gas) + } + + fn blob_sidecar(&self) -> Option<&BlobTransactionSidecar> { + self.sidecar.as_ref() + } + + fn set_blob_sidecar(&mut self, sidecar: BlobTransactionSidecar) { + self.sidecar = Some(sidecar); + self.populate_blob_hashes(); + } +} + +impl TransactionBuilder7702 for TransactionRequest { + fn authorization_list(&self) -> Option<&Vec> { + self.authorization_list.as_ref() + } + + fn set_authorization_list(&mut self, authorization_list: Vec) { + self.authorization_list = Some(authorization_list); + } +} + #[cfg(test)] mod tests { - use crate::{TransactionBuilder, TransactionBuilderError}; + use crate::{ + TransactionBuilder, TransactionBuilder4844, TransactionBuilder7702, TransactionBuilderError, + }; use alloy_consensus::{BlobTransactionSidecar, TxEip1559, TxType, TypedTransaction}; use alloy_eips::eip7702::Authorization; use alloy_primitives::{Address, Signature, U256}; diff --git a/crates/network/src/lib.rs b/crates/network/src/lib.rs index f285150b045..1ae519fdef0 100644 --- a/crates/network/src/lib.rs +++ b/crates/network/src/lib.rs @@ -13,8 +13,8 @@ use core::fmt::{Debug, Display}; mod transaction; pub use transaction::{ - BuildResult, NetworkWallet, TransactionBuilder, TransactionBuilderError, TxSigner, - TxSignerSync, UnbuiltTransactionError, + BuildResult, NetworkWallet, TransactionBuilder, TransactionBuilder4844, TransactionBuilder7702, + TransactionBuilderError, TxSigner, TxSignerSync, UnbuiltTransactionError, }; mod ethereum; diff --git a/crates/network/src/transaction/builder.rs b/crates/network/src/transaction/builder.rs index f2ba6bea84a..a82efceaa12 100644 --- a/crates/network/src/transaction/builder.rs +++ b/crates/network/src/transaction/builder.rs @@ -248,19 +248,6 @@ pub trait TransactionBuilder: Default + Sized + Send + Sync + 'stati self.set_max_priority_fee_per_gas(max_priority_fee_per_gas); self } - - /// Get the max fee per blob gas for the transaction. - fn max_fee_per_blob_gas(&self) -> Option; - - /// Set the max fee per blob gas for the transaction. - fn set_max_fee_per_blob_gas(&mut self, max_fee_per_blob_gas: u128); - - /// Builder-pattern method for setting max fee per blob gas . - fn with_max_fee_per_blob_gas(mut self, max_fee_per_blob_gas: u128) -> Self { - self.set_max_fee_per_blob_gas(max_fee_per_blob_gas); - self - } - /// Get the gas limit for the transaction. fn gas_limit(&self) -> Option; @@ -285,33 +272,6 @@ pub trait TransactionBuilder: Default + Sized + Send + Sync + 'stati self } - /// Gets the EIP-4844 blob sidecar of the transaction. - fn blob_sidecar(&self) -> Option<&BlobTransactionSidecar>; - - /// Sets the EIP-4844 blob sidecar of the transaction. - /// - /// Note: This will also set the versioned blob hashes accordingly: - /// [BlobTransactionSidecar::versioned_hashes] - fn set_blob_sidecar(&mut self, sidecar: BlobTransactionSidecar); - - /// Builder-pattern method for setting the EIP-4844 blob sidecar of the transaction. - fn with_blob_sidecar(mut self, sidecar: BlobTransactionSidecar) -> Self { - self.set_blob_sidecar(sidecar); - self - } - - /// Get the EIP-7702 authorization list for the transaction. - fn authorization_list(&self) -> Option<&Vec>; - - /// Sets the EIP-7702 authorization list. - fn set_authorization_list(&mut self, authorization_list: Vec); - - /// Builder-pattern method for setting the authorization list. - fn with_authorization_list(mut self, authorization_list: Vec) -> Self { - self.set_authorization_list(authorization_list); - self - } - /// Check if all necessary keys are present to build the specified type, /// returning a list of missing keys. fn complete_type(&self, ty: N::TxType) -> Result<(), Vec<&'static str>>; @@ -383,3 +343,48 @@ pub trait TransactionBuilder: Default + Sized + Send + Sync + 'stati wallet: &W, ) -> impl_future!(>>); } + +/// Transaction builder type supporting EIP-4844 transaction fields. +pub trait TransactionBuilder4844: Default + Sized + Send + Sync + 'static { + /// Get the max fee per blob gas for the transaction. + fn max_fee_per_blob_gas(&self) -> Option; + + /// Set the max fee per blob gas for the transaction. + fn set_max_fee_per_blob_gas(&mut self, max_fee_per_blob_gas: u128); + + /// Builder-pattern method for setting max fee per blob gas . + fn with_max_fee_per_blob_gas(mut self, max_fee_per_blob_gas: u128) -> Self { + self.set_max_fee_per_blob_gas(max_fee_per_blob_gas); + self + } + + /// Gets the EIP-4844 blob sidecar of the transaction. + fn blob_sidecar(&self) -> Option<&BlobTransactionSidecar>; + + /// Sets the EIP-4844 blob sidecar of the transaction. + /// + /// Note: This will also set the versioned blob hashes accordingly: + /// [BlobTransactionSidecar::versioned_hashes] + fn set_blob_sidecar(&mut self, sidecar: BlobTransactionSidecar); + + /// Builder-pattern method for setting the EIP-4844 blob sidecar of the transaction. + fn with_blob_sidecar(mut self, sidecar: BlobTransactionSidecar) -> Self { + self.set_blob_sidecar(sidecar); + self + } +} + +/// Transaction builder type supporting EIP-7702 transaction fields. +pub trait TransactionBuilder7702: Default + Sized + Send + Sync + 'static { + /// Get the EIP-7702 authorization list for the transaction. + fn authorization_list(&self) -> Option<&Vec>; + + /// Sets the EIP-7702 authorization list. + fn set_authorization_list(&mut self, authorization_list: Vec); + + /// Builder-pattern method for setting the authorization list. + fn with_authorization_list(mut self, authorization_list: Vec) -> Self { + self.set_authorization_list(authorization_list); + self + } +} diff --git a/crates/network/src/transaction/mod.rs b/crates/network/src/transaction/mod.rs index 3d78d84c0d2..f790970b2e9 100644 --- a/crates/network/src/transaction/mod.rs +++ b/crates/network/src/transaction/mod.rs @@ -1,6 +1,7 @@ mod builder; pub use builder::{ - BuildResult, TransactionBuilder, TransactionBuilderError, UnbuiltTransactionError, + BuildResult, TransactionBuilder, TransactionBuilder4844, TransactionBuilder7702, + TransactionBuilderError, UnbuiltTransactionError, }; mod signer; diff --git a/crates/provider/src/builder.rs b/crates/provider/src/builder.rs index a7e71ef9b17..898f7b5d819 100644 --- a/crates/provider/src/builder.rs +++ b/crates/provider/src/builder.rs @@ -1,7 +1,7 @@ use crate::{ fillers::{ CachedNonceManager, ChainIdFiller, FillerControlFlow, GasFiller, JoinFill, NonceFiller, - NonceManager, RecommendedFiller, SimpleNonceManager, TxFiller, WalletFiller, + NonceManager, RecommendedFillers, SimpleNonceManager, TxFiller, WalletFiller, }, provider::SendableTx, Provider, RootProvider, @@ -130,8 +130,13 @@ impl Default for ProviderBuilder { impl ProviderBuilder { /// Add preconfigured set of layers handling gas estimation, nonce /// management, and chain-id fetching. - pub fn with_recommended_fillers(self) -> ProviderBuilder { - self.filler(GasFiller).filler(NonceFiller::default()).filler(ChainIdFiller::default()) + pub fn with_recommended_fillers( + self, + ) -> ProviderBuilder, N> + where + N: RecommendedFillers, + { + self.filler(N::recommended_fillers()) } /// Add gas estimation to the stack being built. diff --git a/crates/provider/src/fillers/gas.rs b/crates/provider/src/fillers/gas.rs index 1c6c646fbf9..6c484329762 100644 --- a/crates/provider/src/fillers/gas.rs +++ b/crates/provider/src/fillers/gas.rs @@ -7,7 +7,7 @@ use crate::{ Provider, }; use alloy_json_rpc::RpcError; -use alloy_network::{Network, TransactionBuilder}; +use alloy_network::{Network, TransactionBuilder, TransactionBuilder4844}; use alloy_network_primitives::{BlockResponse, HeaderResponse}; use alloy_rpc_types_eth::BlockNumberOrTag; use alloy_transport::{Transport, TransportResult}; @@ -19,7 +19,6 @@ use futures::FutureExt; pub enum GasFillable { Legacy { gas_limit: u128, gas_price: u128 }, Eip1559 { gas_limit: u128, estimate: Eip1559Estimation }, - Eip4844 { gas_limit: u128, estimate: Eip1559Estimation, max_fee_per_blob_gas: u128 }, } /// A [`TxFiller`] that populates gas related fields in transaction requests if @@ -65,6 +64,10 @@ pub enum GasFillable { #[derive(Clone, Copy, Debug, Default)] pub struct GasFiller; +/// Filler for the `max_fee_per_blob_gas` field in EIP-4844 transactions. +#[derive(Clone, Copy, Debug, Default)] +pub struct BlobGasFiller; + impl GasFiller { async fn prepare_legacy( &self, @@ -119,52 +122,6 @@ impl GasFiller { Ok(GasFillable::Eip1559 { gas_limit, estimate }) } - - async fn prepare_4844( - &self, - provider: &P, - tx: &N::TransactionRequest, - ) -> TransportResult - where - P: Provider, - T: Transport + Clone, - N: Network, - { - let gas_limit_fut = tx.gas_limit().map_or_else( - || provider.estimate_gas(tx).into_future().right_future(), - |gas_limit| async move { Ok(gas_limit) }.left_future(), - ); - - let eip1559_fees_fut = if let (Some(max_fee_per_gas), Some(max_priority_fee_per_gas)) = - (tx.max_fee_per_gas(), tx.max_priority_fee_per_gas()) - { - async move { Ok(Eip1559Estimation { max_fee_per_gas, max_priority_fee_per_gas }) } - .left_future() - } else { - provider.estimate_eip1559_fees(None).right_future() - }; - - let max_fee_per_blob_gas_fut = tx.max_fee_per_blob_gas().map_or_else( - || { - async { - provider - .get_block_by_number(BlockNumberOrTag::Latest, false) - .await? - .ok_or(RpcError::NullResp)? - .header() - .next_block_blob_fee() - .ok_or(RpcError::UnsupportedFeature("eip4844")) - } - .right_future() - }, - |max_fee_per_blob_gas| async move { Ok(max_fee_per_blob_gas) }.left_future(), - ); - - let (gas_limit, estimate, max_fee_per_blob_gas) = - futures::try_join!(gas_limit_fut, eip1559_fees_fut, max_fee_per_blob_gas_fut)?; - - Ok(GasFillable::Eip4844 { gas_limit, estimate, max_fee_per_blob_gas }) - } } impl TxFiller for GasFiller { @@ -176,18 +133,8 @@ impl TxFiller for GasFiller { return FillerControlFlow::Finished; } - // 4844 - if tx.max_fee_per_blob_gas().is_some() - && tx.max_fee_per_gas().is_some() - && tx.max_priority_fee_per_gas().is_some() - && tx.gas_limit().is_some() - { - return FillerControlFlow::Finished; - } - // eip1559 - if tx.blob_sidecar().is_none() - && tx.max_fee_per_gas().is_some() + if tx.max_fee_per_gas().is_some() && tx.max_priority_fee_per_gas().is_some() && tx.gas_limit().is_some() { @@ -208,10 +155,8 @@ impl TxFiller for GasFiller { P: Provider, T: Transport + Clone, { - if tx.gas_price().is_some() || tx.access_list().is_some() { + if tx.gas_price().is_some() { self.prepare_legacy(provider, tx).await - } else if tx.blob_sidecar().is_some() { - self.prepare_4844(provider, tx).await } else { match self.prepare_1559(provider, tx).await { // fallback to legacy @@ -238,18 +183,62 @@ impl TxFiller for GasFiller { builder.set_max_fee_per_gas(estimate.max_fee_per_gas); builder.set_max_priority_fee_per_gas(estimate.max_priority_fee_per_gas); } - GasFillable::Eip4844 { gas_limit, estimate, max_fee_per_blob_gas } => { - builder.set_gas_limit(gas_limit); - builder.set_max_fee_per_gas(estimate.max_fee_per_gas); - builder.set_max_priority_fee_per_gas(estimate.max_priority_fee_per_gas); - builder.set_max_fee_per_blob_gas(max_fee_per_blob_gas); - } } }; Ok(tx) } } +impl TxFiller for BlobGasFiller +where + N::TransactionRequest: TransactionBuilder4844, +{ + type Fillable = u128; + + fn status(&self, tx: &::TransactionRequest) -> FillerControlFlow { + // nothing to fill if non-eip4844 tx or max_fee_per_blob_gas is already set + if tx.blob_sidecar().is_none() || tx.max_fee_per_blob_gas().is_some() { + return FillerControlFlow::Finished; + } + + FillerControlFlow::Ready + } + + fn fill_sync(&self, _tx: &mut SendableTx) {} + + async fn prepare( + &self, + provider: &P, + tx: &::TransactionRequest, + ) -> TransportResult + where + P: Provider, + T: Transport + Clone, + { + if let Some(max_fee_per_blob_gas) = tx.max_fee_per_blob_gas() { + return Ok(max_fee_per_blob_gas); + } + provider + .get_block_by_number(BlockNumberOrTag::Latest, false) + .await? + .ok_or(RpcError::NullResp)? + .header() + .next_block_blob_fee() + .ok_or(RpcError::UnsupportedFeature("eip4844")) + } + + async fn fill( + &self, + fillable: Self::Fillable, + mut tx: SendableTx, + ) -> TransportResult> { + if let Some(builder) = tx.as_mut_builder() { + builder.set_max_fee_per_blob_gas(fillable); + } + Ok(tx) + } +} + #[cfg(feature = "reqwest")] #[cfg(test)] mod tests { @@ -300,24 +289,4 @@ mod tests { assert_eq!(receipt.gas_used, 0x5208); } - - #[tokio::test] - async fn non_eip1559_network() { - let provider = ProviderBuilder::new().with_recommended_fillers().on_anvil(); - - let tx = TransactionRequest { - from: Some(address!("f39Fd6e51aad88F6F4ce6aB8827279cffFb92266")), - value: Some(U256::from(100)), - to: Some(address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045").into()), - // access list forces legacy gassing - access_list: Some(vec![Default::default()].into()), - ..Default::default() - }; - - let tx = provider.send_transaction(tx).await.unwrap(); - - let receipt = tx.get_receipt().await.unwrap(); - - assert_eq!(receipt.effective_gas_price, 2000000000); - } } diff --git a/crates/provider/src/fillers/mod.rs b/crates/provider/src/fillers/mod.rs index e487d9f0fe4..fed8afeaddd 100644 --- a/crates/provider/src/fillers/mod.rs +++ b/crates/provider/src/fillers/mod.rs @@ -16,7 +16,7 @@ mod nonce; pub use nonce::{CachedNonceManager, NonceFiller, NonceManager, SimpleNonceManager}; mod gas; -pub use gas::{GasFillable, GasFiller}; +pub use gas::{BlobGasFiller, GasFillable, GasFiller}; mod join_fill; pub use join_fill::JoinFill; @@ -27,7 +27,7 @@ use crate::{ RootProvider, }; use alloy_json_rpc::RpcError; -use alloy_network::{Ethereum, Network}; +use alloy_network::{AnyNetwork, Ethereum, Network}; use alloy_transport::{Transport, TransportResult}; use async_trait::async_trait; use futures_utils_wasm::impl_future; @@ -308,3 +308,42 @@ where self.inner.send_transaction_internal(tx).await } } + +/// A trait which may be used to configure default fillers for [Network] implementations. +pub trait RecommendedFillers { + /// Recommended fillers for this network. + type RecomendedFillters: TxFiller; + + /// Returns the recommended filler for this provider. + fn recommended_fillers() -> Self::RecomendedFillters; +} + +impl RecommendedFillers for Ethereum { + type RecomendedFillters = + JoinFill>>; + + fn recommended_fillers() -> Self::RecomendedFillters { + JoinFill::new( + GasFiller, + JoinFill::new( + BlobGasFiller, + JoinFill::new(NonceFiller::default(), ChainIdFiller::default()), + ), + ) + } +} + +impl RecommendedFillers for AnyNetwork { + type RecomendedFillters = + JoinFill>>; + + fn recommended_fillers() -> Self::RecomendedFillters { + JoinFill::new( + GasFiller, + JoinFill::new( + BlobGasFiller, + JoinFill::new(NonceFiller::default(), ChainIdFiller::default()), + ), + ) + } +} From a0eea365c1241b27b8a87bd88544ebc7f40a3c3f Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Tue, 17 Sep 2024 22:20:52 +0530 Subject: [PATCH 177/186] feat(`node-bindings`): support appending extra args (#1299) * feat(`node-bindings`): support appending args that are not part of the builder api * use OsString --- crates/node-bindings/src/nodes/anvil.rs | 7 ++++--- crates/node-bindings/src/nodes/geth.rs | 26 +++++++++++++++++++++++ crates/node-bindings/src/nodes/reth.rs | 28 +++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/crates/node-bindings/src/nodes/anvil.rs b/crates/node-bindings/src/nodes/anvil.rs index 95ec994b018..5c050f14f8d 100644 --- a/crates/node-bindings/src/nodes/anvil.rs +++ b/crates/node-bindings/src/nodes/anvil.rs @@ -3,6 +3,7 @@ use alloy_primitives::{hex, Address, ChainId}; use k256::{ecdsa::SigningKey, SecretKey as K256SecretKey}; use std::{ + ffi::OsString, io::{BufRead, BufReader}, net::SocketAddr, path::PathBuf, @@ -123,7 +124,7 @@ pub struct Anvil { mnemonic: Option, fork: Option, fork_block_number: Option, - args: Vec, + args: Vec, timeout: Option, } @@ -219,7 +220,7 @@ impl Anvil { } /// Adds an argument to pass to the `anvil`. - pub fn arg>(mut self, arg: T) -> Self { + pub fn arg>(mut self, arg: T) -> Self { self.args.push(arg.into()); self } @@ -228,7 +229,7 @@ impl Anvil { pub fn args(mut self, args: I) -> Self where I: IntoIterator, - S: Into, + S: Into, { for arg in args { self = self.arg(arg); diff --git a/crates/node-bindings/src/nodes/geth.rs b/crates/node-bindings/src/nodes/geth.rs index fd7e200f6a0..3e36f096a67 100644 --- a/crates/node-bindings/src/nodes/geth.rs +++ b/crates/node-bindings/src/nodes/geth.rs @@ -8,6 +8,7 @@ use alloy_genesis::{CliqueConfig, Genesis}; use alloy_primitives::Address; use k256::ecdsa::SigningKey; use std::{ + ffi::OsString, fs::{create_dir, File}, io::{BufRead, BufReader}, path::PathBuf, @@ -204,6 +205,7 @@ pub struct Geth { genesis: Option, mode: NodeMode, clique_private_key: Option, + args: Vec, } impl Geth { @@ -367,6 +369,28 @@ impl Geth { self } + /// Adds an argument to pass to `geth`. + /// + /// Pass any arg that is not supported by the builder. + pub fn arg>(mut self, arg: T) -> Self { + self.args.push(arg.into()); + self + } + + /// Adds multiple arguments to pass to `geth`. + /// + /// Pass any args that is not supported by the builder. + pub fn args(mut self, args: I) -> Self + where + I: IntoIterator, + S: Into, + { + for arg in args { + self = self.arg(arg); + } + self + } + /// Consumes the builder and spawns `geth`. /// /// # Panics @@ -543,6 +567,8 @@ impl Geth { cmd.arg("--ipcpath").arg(ipc); } + cmd.args(self.args); + let mut child = cmd.spawn().map_err(NodeError::SpawnError)?; let stderr = child.stderr.take().ok_or(NodeError::NoStderr)?; diff --git a/crates/node-bindings/src/nodes/reth.rs b/crates/node-bindings/src/nodes/reth.rs index f465f004915..80d0632cc3c 100644 --- a/crates/node-bindings/src/nodes/reth.rs +++ b/crates/node-bindings/src/nodes/reth.rs @@ -4,6 +4,7 @@ use crate::{utils::extract_endpoint, NodeError, NODE_STARTUP_TIMEOUT}; use alloy_genesis::Genesis; use rand::Rng; use std::{ + ffi::OsString, fs::create_dir, io::{BufRead, BufReader}, path::PathBuf, @@ -160,6 +161,7 @@ pub struct Reth { data_dir: Option, chain_or_path: Option, genesis: Option, + args: Vec, } impl Reth { @@ -184,6 +186,7 @@ impl Reth { data_dir: None, chain_or_path: None, genesis: None, + args: Vec::new(), } } @@ -306,6 +309,28 @@ impl Reth { self } + /// Adds an argument to pass to `reth`. + /// + /// Pass any arg that is not supported by the builder. + pub fn arg>(mut self, arg: T) -> Self { + self.args.push(arg.into()); + self + } + + /// Adds multiple arguments to pass to `reth`. + /// + /// Pass any args that is not supported by the builder. + pub fn args(mut self, args: I) -> Self + where + I: IntoIterator, + S: Into, + { + for arg in args { + self = self.arg(arg); + } + self + } + /// Consumes the builder and spawns `reth`. /// /// # Panics @@ -413,6 +438,9 @@ impl Reth { // Disable color output to make parsing logs easier. cmd.arg("--color").arg("never"); + // Add any additional arguments. + cmd.args(self.args); + let mut child = cmd.spawn().map_err(NodeError::SpawnError)?; let stdout = child.stdout.take().ok_or(NodeError::NoStdout)?; From 7424f09393c1cf05547773795ef42081d1df09a4 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 17 Sep 2024 19:39:05 +0200 Subject: [PATCH 178/186] feat: add types for flat call tracer (#1292) --- crates/rpc-types-trace/src/geth/call.rs | 33 +++++++++++++++++++++++ crates/rpc-types-trace/src/geth/mod.rs | 36 ++++++++++++++++++++++--- 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/crates/rpc-types-trace/src/geth/call.rs b/crates/rpc-types-trace/src/geth/call.rs index 5555b9acba5..5a1cb126ea3 100644 --- a/crates/rpc-types-trace/src/geth/call.rs +++ b/crates/rpc-types-trace/src/geth/call.rs @@ -1,5 +1,6 @@ //! Geth call tracer types. +use crate::parity::LocalizedTransactionTrace; use alloy_primitives::{Address, Bytes, B256, U256}; use serde::{Deserialize, Serialize}; @@ -88,6 +89,38 @@ impl CallConfig { } } +/// The response object for `debug_traceTransaction` with `"tracer": "flatCallTracer"`. +/// +/// That is equivalent to parity's [`LocalizedTransactionTrace`] +/// +pub type FlatCallFrame = LocalizedTransactionTrace; + +/// The configuration for the flat call tracer. +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct FlatCallConfig { + /// If true, call tracer converts errors to parity format + #[serde(default, skip_serializing_if = "Option::is_none")] + pub convert_parity_errors: Option, + /// If true, call tracer includes calls to precompiled contracts + #[serde(default, skip_serializing_if = "Option::is_none")] + pub include_precompiles: Option, +} + +impl FlatCallConfig { + /// Converts errors to parity format. + pub const fn parity_errors(mut self) -> Self { + self.convert_parity_errors = Some(true); + self + } + + /// Include calls to precompiled contracts. + pub const fn with_precompiles(mut self) -> Self { + self.include_precompiles = Some(true); + self + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/rpc-types-trace/src/geth/mod.rs b/crates/rpc-types-trace/src/geth/mod.rs index ea8c94026d5..9b64b642052 100644 --- a/crates/rpc-types-trace/src/geth/mod.rs +++ b/crates/rpc-types-trace/src/geth/mod.rs @@ -1,14 +1,16 @@ //! Geth tracing types. -use crate::geth::mux::{MuxConfig, MuxFrame}; +use crate::geth::{ + call::FlatCallFrame, + mux::{MuxConfig, MuxFrame}, +}; use alloy_primitives::{Bytes, B256, U256}; use alloy_rpc_types_eth::{state::StateOverride, BlockOverrides}; use serde::{de::DeserializeOwned, ser::SerializeMap, Deserialize, Serialize, Serializer}; use std::{collections::BTreeMap, time::Duration}; - // re-exports pub use self::{ - call::{CallConfig, CallFrame, CallLogFrame}, + call::{CallConfig, CallFrame, CallLogFrame, FlatCallConfig}, four_byte::FourByteFrame, noop::NoopFrame, pre_state::{ @@ -118,6 +120,8 @@ pub enum GethTrace { Default(DefaultFrame), /// The response for call tracer CallTracer(CallFrame), + /// The response for the flat call tracer + FlatCallTracer(FlatCallFrame), /// The response for four byte tracer FourByteTracer(FourByteFrame), /// The response for pre-state byte tracer @@ -147,6 +151,14 @@ impl GethTrace { } } + /// Try to convert the inner tracer to [FlatCallFrame] + pub fn try_into_flat_call_frame(self) -> Result { + match self { + Self::FlatCallTracer(inner) => Ok(inner), + _ => Err(UnexpectedTracerError(self)), + } + } + /// Try to convert the inner tracer to [FourByteFrame] pub fn try_into_four_byte_frame(self) -> Result { match self { @@ -212,6 +224,12 @@ impl From for GethTrace { } } +impl From for GethTrace { + fn from(value: FlatCallFrame) -> Self { + Self::FlatCallTracer(value) + } +} + impl From for GethTrace { fn from(value: PreStateFrame) -> Self { Self::PreStateTracer(value) @@ -246,6 +264,10 @@ pub enum GethDebugBuiltInTracerType { /// with the top-level call at root and sub-calls as children of the higher levels. #[serde(rename = "callTracer")] CallTracer, + /// Tracks all call frames of a transaction and returns them in a flat format, i.e. as opposed + /// to the nested format of `callTracer`. + #[serde(rename = "flatCallTracer")] + FlatCallTracer, /// The prestate tracer has two modes: prestate and diff. The prestate mode returns the /// accounts necessary to execute a given transaction. diff mode returns the differences /// between the transaction's pre and post-state (i.e. what changed because the transaction @@ -311,6 +333,14 @@ impl GethDebugTracerConfig { self.from_value() } + /// Returns the [FlatCallConfig] if it is a call config. + pub fn into_flat_call_config(self) -> Result { + if self.0.is_null() { + return Ok(Default::default()); + } + self.from_value() + } + /// Returns the raw json value pub fn into_json(self) -> serde_json::Value { self.0 From 6c409bd78f118077237283581998a4e082ab4b50 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Tue, 17 Sep 2024 20:13:22 +0200 Subject: [PATCH 179/186] feat: add blob and proof v1 (#1300) --- crates/eips/src/eip4844/engine.rs | 14 ++++++++++++++ crates/eips/src/eip4844/mod.rs | 3 +++ 2 files changed, 17 insertions(+) create mode 100644 crates/eips/src/eip4844/engine.rs diff --git a/crates/eips/src/eip4844/engine.rs b/crates/eips/src/eip4844/engine.rs new file mode 100644 index 00000000000..b8bb0146238 --- /dev/null +++ b/crates/eips/src/eip4844/engine.rs @@ -0,0 +1,14 @@ +//! Misc types related to the 4844 + +use crate::eip4844::{Blob, Bytes48}; +use alloc::boxed::Box; + +/// Blob type returned in responses to `engine_getBlobsV1`: +#[derive(Debug, Clone, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +pub struct BlobAndProofV1 { + /// The blob data. + pub blob: Box, + /// The KZG proof for the blob. + pub proof: Bytes48, +} diff --git a/crates/eips/src/eip4844/mod.rs b/crates/eips/src/eip4844/mod.rs index dbba4352d44..99e315555ea 100644 --- a/crates/eips/src/eip4844/mod.rs +++ b/crates/eips/src/eip4844/mod.rs @@ -13,6 +13,9 @@ pub mod trusted_setup_points; pub mod builder; pub mod utils; +mod engine; +pub use engine::*; + /// Contains sidecar related types #[cfg(feature = "kzg-sidecar")] mod sidecar; From 347626b0609c31d6ea740d4a8c770e01b241004a Mon Sep 17 00:00:00 2001 From: Roman Krasiuk Date: Tue, 17 Sep 2024 20:44:27 +0200 Subject: [PATCH 180/186] chore(rpc): rename witness fields (#1293) * chore(rpc): rename witness fields * chore: allow missing keys --------- Co-authored-by: Matthias Seitz --- crates/rpc-types-debug/src/debug.rs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/crates/rpc-types-debug/src/debug.rs b/crates/rpc-types-debug/src/debug.rs index f1cbf76f44b..ea3c1d770db 100644 --- a/crates/rpc-types-debug/src/debug.rs +++ b/crates/rpc-types-debug/src/debug.rs @@ -9,9 +9,12 @@ use std::collections::HashMap; pub struct ExecutionWitness { /// Map of all hashed trie nodes to their preimages that were required during the execution of /// the block, including during state root recomputation. - pub witness: HashMap, - /// Map of all hashed account addresses and storage slots to their preimages (unhashed account - /// addresses and storage slots, respectively) that were required during the execution of the - /// block. during the execution of the block. - pub state_preimages: Option>, + /// keccak(rlp(node)) => rlp(node) + pub state: HashMap, + /// Map of all hashed account and storage keys (addresses and slots) to their preimages + /// (unhashed account addresses and storage slots, respectively) that were required during + /// the execution of the block. during the execution of the block. + /// keccak(address|slot) => address|slot + #[serde(default)] + pub keys: Option>, } From 68115f5665a26ad345ac8525d385c5ddef62fc73 Mon Sep 17 00:00:00 2001 From: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Date: Wed, 18 Sep 2024 15:13:26 +0530 Subject: [PATCH 181/186] feat(transport-http): layer client (#1227) * feat(transport): bare minimal reqwest-tower integration * feat(transport-http): reqwest-tower layer client * feat(transport-http): LayerClient * fix: feature gate layer transport * rm logging layer * feat(transport-http): hyper layer transport * hyper layer transport test * test with tower-http layers * rm reqwest layer transport * rm trait bounds for new * nit * unify hyper transports * rm TransportConnect for HyperLayerTransport * make request generic * unify hyper transports * nit * nit * nit * rm unintended reqwest default * rename HyperLayerTransport to HyperTransport * rename file * nit * fix: rm transport from HttpConnect * fix: rm url from HyperTransport, infer it from Http * clippy * fix * impl Http * fix * rename * nit --- Cargo.toml | 2 + crates/alloy/Cargo.toml | 9 +- crates/provider/Cargo.toml | 11 +- crates/provider/src/builder.rs | 13 +- crates/provider/src/lib.rs | 2 +- crates/provider/src/provider/trait.rs | 124 ++++++++++++++++++ crates/rpc-client/Cargo.toml | 4 +- crates/rpc-client/src/builder.rs | 6 +- crates/transport-http/src/hyper_transport.rs | 127 +++++++++++++------ crates/transport-http/src/lib.rs | 19 +-- 10 files changed, 247 insertions(+), 70 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9290524cab8..416cce9e400 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -138,6 +138,7 @@ thiserror = "1.0" thiserror-no-std = "2.0.2" url = "2.5" derive_more = { version = "1.0.0", default-features = false } +http = "1.1.0" ## serde serde = { version = "1.0", default-features = false, features = [ @@ -153,3 +154,4 @@ assert_matches = "1.5" serial_test = "3.0" similar-asserts = "1.5" tempfile = "3.10" +tower-http = "0.5.2" diff --git a/crates/alloy/Cargo.toml b/crates/alloy/Cargo.toml index cbea4be8d4d..ef4a91b1b79 100644 --- a/crates/alloy/Cargo.toml +++ b/crates/alloy/Cargo.toml @@ -131,7 +131,14 @@ network = ["dep:alloy-network"] node-bindings = ["dep:alloy-node-bindings", "alloy-provider?/anvil-node"] # providers -providers = ["dep:alloy-provider", "rpc-client", "transports", "eips", "consensus", "network"] +providers = [ + "dep:alloy-provider", + "rpc-client", + "transports", + "eips", + "consensus", + "network", +] provider-http = ["providers", "transport-http"] provider-ws = ["providers", "alloy-provider?/ws", "transport-ws"] provider-ipc = ["providers", "alloy-provider?/ipc", "transport-ipc"] diff --git a/crates/provider/Cargo.toml b/crates/provider/Cargo.toml index a2fc9d81338..12444152f42 100644 --- a/crates/provider/Cargo.toml +++ b/crates/provider/Cargo.toml @@ -32,7 +32,9 @@ 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, features = ["serde"] } +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 } @@ -73,6 +75,13 @@ reqwest.workspace = true tokio = { workspace = true, features = ["macros"] } tracing-subscriber = { workspace = true, features = ["fmt"] } tempfile.workspace = true +tower.workspace = true +tower-http = { workspace = true, features = [ + "set-header", + "sensitive-headers", +] } +http-body-util.workspace = true +http.workspace = true [features] default = ["reqwest", "reqwest-default-tls"] diff --git a/crates/provider/src/builder.rs b/crates/provider/src/builder.rs index 898f7b5d819..fedf12dd269 100644 --- a/crates/provider/src/builder.rs +++ b/crates/provider/src/builder.rs @@ -354,17 +354,8 @@ impl ProviderBuilder { #[cfg(feature = "hyper")] pub fn on_hyper_http(self, url: url::Url) -> F::Provider where - L: ProviderLayer< - crate::HyperProvider, - alloy_transport_http::Http, - N, - >, - F: TxFiller - + ProviderLayer< - L::Provider, - alloy_transport_http::Http, - N, - >, + L: ProviderLayer, alloy_transport_http::HyperTransport, N>, + F: TxFiller + ProviderLayer, N: Network, { let client = ClientBuilder::default().hyper_http(url); diff --git a/crates/provider/src/lib.rs b/crates/provider/src/lib.rs index 416c98da727..a59bdc8c0fb 100644 --- a/crates/provider/src/lib.rs +++ b/crates/provider/src/lib.rs @@ -20,7 +20,7 @@ pub type ReqwestProvider = /// [`Http`]: alloy_transport_http::Http #[cfg(feature = "hyper")] pub type HyperProvider = - crate::RootProvider, N>; + crate::RootProvider; #[macro_use] extern crate tracing; diff --git a/crates/provider/src/provider/trait.rs b/crates/provider/src/provider/trait.rs index 17393c9c35e..c522c8a3799 100644 --- a/crates/provider/src/provider/trait.rs +++ b/crates/provider/src/provider/trait.rs @@ -1013,6 +1013,21 @@ mod tests { use alloy_node_bindings::Anvil; use alloy_primitives::{address, b256, bytes, keccak256}; use alloy_rpc_types_eth::{request::TransactionRequest, Block}; + // For layer transport tests + #[cfg(feature = "hyper")] + use alloy_transport_http::{ + hyper, + hyper::body::Bytes as HyperBytes, + hyper_util::{ + client::legacy::{Client, Error}, + rt::TokioExecutor, + }, + HyperResponse, HyperResponseFut, + }; + #[cfg(feature = "hyper")] + use http_body_util::Full; + #[cfg(feature = "hyper")] + use tower::{Layer, Service}; fn init_tracing() { let _ = tracing_subscriber::fmt::try_init(); @@ -1035,6 +1050,115 @@ mod tests { assert_eq!(0, num); } + #[cfg(feature = "hyper")] + #[tokio::test] + async fn test_default_hyper_transport() { + init_tracing(); + let anvil = Anvil::new().spawn(); + let hyper_t = alloy_transport_http::HyperTransport::new_hyper(anvil.endpoint_url()); + + let rpc_client = alloy_rpc_client::RpcClient::new(hyper_t, true); + + let provider = RootProvider::<_, Ethereum>::new(rpc_client); + let num = provider.get_block_number().await.unwrap(); + assert_eq!(0, num); + } + + #[cfg(feature = "hyper")] + #[tokio::test] + async fn test_hyper_layer_transport() { + struct LoggingLayer; + + impl Layer for LoggingLayer { + type Service = LoggingService; + + fn layer(&self, inner: S) -> Self::Service { + LoggingService { inner } + } + } + + #[derive(Clone)] // required + struct LoggingService { + inner: S, + } + + impl Service> for LoggingService + where + S: Service, Response = HyperResponse, Error = Error> + + Clone + + Send + + Sync + + 'static, + S::Future: Send, + S::Error: std::error::Error + Send + Sync + 'static, + B: From> + Send + 'static + Clone + Sync + std::fmt::Debug, + { + type Response = HyperResponse; + type Error = Error; + type Future = HyperResponseFut; + + fn poll_ready( + &mut self, + cx: &mut std::task::Context<'_>, + ) -> std::task::Poll> { + self.inner.poll_ready(cx) + } + + fn call(&mut self, req: hyper::Request) -> Self::Future { + println!("Logging Layer - HyperRequest {req:?}"); + + let fut = self.inner.call(req); + + Box::pin(fut) + } + } + use http::header::{self, HeaderValue}; + use tower_http::{ + sensitive_headers::SetSensitiveRequestHeadersLayer, set_header::SetRequestHeaderLayer, + }; + init_tracing(); + let anvil = Anvil::new().spawn(); + let hyper_client = Client::builder(TokioExecutor::new()).build_http::>(); + + // Setup tower serive with multiple layers modifying request headers + let service = tower::ServiceBuilder::new() + .layer(SetRequestHeaderLayer::if_not_present( + header::USER_AGENT, + HeaderValue::from_static("alloy app"), + )) + .layer(SetRequestHeaderLayer::overriding( + header::AUTHORIZATION, + HeaderValue::from_static("some-jwt-token"), + )) + .layer(SetRequestHeaderLayer::appending( + header::SET_COOKIE, + HeaderValue::from_static("cookie-value"), + )) + .layer(SetSensitiveRequestHeadersLayer::new([header::AUTHORIZATION])) // Hides the jwt token as sensitive. + .layer(LoggingLayer) + .service(hyper_client); + + let layer_transport = alloy_transport_http::HyperClient::with_service(service); + + let http_hyper = + alloy_transport_http::Http::with_client(layer_transport, anvil.endpoint_url()); + + let rpc_client = alloy_rpc_client::RpcClient::new(http_hyper, true); + + let provider = RootProvider::<_, Ethereum>::new(rpc_client); + let num = provider.get_block_number().await.unwrap(); + assert_eq!(0, num); + + // Test Cloning with service + let cloned_t = provider.client().transport().clone(); + + let rpc_client = alloy_rpc_client::RpcClient::new(cloned_t, true); + + let provider = RootProvider::<_, Ethereum>::new(rpc_client); + let num = provider.get_block_number().await.unwrap(); + assert_eq!(0, num); + } + #[tokio::test] async fn test_builder_helper_fn_any_network() { init_tracing(); diff --git a/crates/rpc-client/Cargo.toml b/crates/rpc-client/Cargo.toml index 74f7e1c7dbf..ef694848afb 100644 --- a/crates/rpc-client/Cargo.toml +++ b/crates/rpc-client/Cargo.toml @@ -38,8 +38,6 @@ alloy-transport-ws = { workspace = true, optional = true } reqwest = { workspace = true, optional = true } -hyper-util = { workspace = true, optional = true } - url = { workspace = true, optional = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] @@ -57,7 +55,7 @@ futures-util.workspace = true [features] default = ["reqwest"] reqwest = ["dep:url", "dep:reqwest", "alloy-transport-http/reqwest"] -hyper = ["dep:url", "dep:hyper-util", "alloy-transport-http/hyper"] +hyper = ["dep:url", "alloy-transport-http/hyper"] pubsub = ["dep:alloy-pubsub", "dep:alloy-primitives"] ws = ["pubsub", "dep:alloy-transport-ws", "dep:url"] ipc = ["pubsub", "dep:alloy-transport-ipc"] diff --git a/crates/rpc-client/src/builder.rs b/crates/rpc-client/src/builder.rs index 28be4963a76..759affd3608 100644 --- a/crates/rpc-client/src/builder.rs +++ b/crates/rpc-client/src/builder.rs @@ -64,12 +64,10 @@ impl ClientBuilder { #[cfg(all(not(target_arch = "wasm32"), feature = "hyper"))] pub fn hyper_http(self, url: url::Url) -> RpcClient where - L: Layer>, + L: Layer, L::Service: Transport, { - let executor = hyper_util::rt::TokioExecutor::new(); - let client = hyper_util::client::legacy::Client::builder(executor).build_http(); - let transport = alloy_transport_http::Http::with_client(client, url); + let transport = alloy_transport_http::HyperTransport::new_hyper(url); let is_local = transport.guess_local(); self.transport(transport, is_local) diff --git a/crates/transport-http/src/hyper_transport.rs b/crates/transport-http/src/hyper_transport.rs index a92a941ee07..389d0289c03 100644 --- a/crates/transport-http/src/hyper_transport.rs +++ b/crates/transport-http/src/hyper_transport.rs @@ -1,63 +1,92 @@ -use crate::{Http, HttpConnect}; use alloy_json_rpc::{RequestPacket, ResponsePacket}; use alloy_transport::{ utils::guess_local_url, TransportConnect, TransportError, TransportErrorKind, TransportFut, }; use http_body_util::{BodyExt, Full}; use hyper::{ - body::{Buf, Bytes}, - header, + body::{Bytes, Incoming}, + header, Request, Response, }; -use hyper_util::client::legacy::{connect::Connect, Client}; -use std::task; +use hyper_util::client::legacy::Error; +use std::{future::Future, marker::PhantomData, pin::Pin, task}; use tower::Service; use tracing::{debug, debug_span, trace, Instrument}; -/// A [`hyper`] HTTP client. -pub type HyperClient = hyper_util::client::legacy::Client< +use crate::{Http, HttpConnect}; + +type Hyper = hyper_util::client::legacy::Client< hyper_util::client::legacy::connect::HttpConnector, http_body_util::Full<::hyper::body::Bytes>, >; -/// An [`Http`] transport using [`hyper`]. +/// A [`hyper`] based transport client. pub type HyperTransport = Http; -/// Connection details for a [`HyperTransport`]. -pub type HyperConnect = HttpConnect; +impl HyperTransport { + /// Create a new [`HyperTransport`] with the given URL and default hyper client. + pub fn new_hyper(url: url::Url) -> Self { + let client = HyperClient::new(); + Self::with_client(client, url) + } +} -impl TransportConnect for HyperConnect { - type Transport = HyperTransport; +/// A [hyper] based client that can be used with tower layers. +#[derive(Clone, Debug)] +pub struct HyperClient, S = Hyper> { + service: S, + _pd: PhantomData, +} - fn is_local(&self) -> bool { - guess_local_url(self.url.as_str()) - } +/// Alias for [`Response`] +pub type HyperResponse = Response; - fn get_transport<'a: 'b, 'b>( - &'a self, - ) -> alloy_transport::Pbf<'b, Self::Transport, TransportError> { +/// Alias for pinned box future that results in [`HyperResponse`] +pub type HyperResponseFut = + Pin> + Send + 'static>>; + +impl HyperClient { + /// Create a new [HyperClient] with the given URL and default hyper client. + pub fn new() -> Self { let executor = hyper_util::rt::TokioExecutor::new(); - let client = hyper_util::client::legacy::Client::builder(executor).build_http(); + let service = + hyper_util::client::legacy::Client::builder(executor).build_http::>(); - Box::pin(async move { Ok(Http::with_client(client, self.url.clone())) }) + Self { service, _pd: PhantomData } } } -impl Http>> +impl Default for HyperClient { + fn default() -> Self { + Self::new() + } +} + +impl HyperClient { + /// Create a new [HyperClient] with the given URL and service. + pub const fn with_service(service: S) -> Self { + Self { service, _pd: PhantomData } + } +} + +impl Http> where - C: Connect + Clone + Send + Sync + 'static, - B: From + Buf + Send + 'static, + S: Service, Response = HyperResponse> + Clone + Send + Sync + 'static, + S::Future: Send, + S::Error: std::error::Error + Send + Sync + 'static, + B: From> + Send + 'static + Clone, { - /// Make a request. + /// Make a request to the server using the given service. fn request_hyper(&self, req: RequestPacket) -> TransportFut<'static> { let this = self.clone(); - let span = debug_span!("HyperTransport", url = %self.url); + let span = debug_span!("HyperClient", url = %this.url); Box::pin( async move { debug!(count = req.len(), "sending request packet to server"); let ser = req.serialize().map_err(TransportError::ser_err)?; // convert the Box into a hyper request - let body = Full::from(Bytes::from(>::from(>::from(ser)))); + let body = ser.get().as_bytes().to_owned().into(); + let req = hyper::Request::builder() .method(hyper::Method::POST) .uri(this.url.as_str()) @@ -66,9 +95,11 @@ where header::HeaderValue::from_static("application/json"), ) .body(body) - .expect("request parts are valid"); + .expect("request parts are invalid"); + + let mut service = this.client.service.clone(); + let resp = service.call(req).await.map_err(TransportErrorKind::custom)?; - let resp = this.client.request(req).await.map_err(TransportErrorKind::custom)?; let status = resp.status(); debug!(%status, "received response from server"); @@ -105,43 +136,59 @@ where } } -impl Service for &Http>> +impl TransportConnect for HttpConnect { + type Transport = HyperTransport; + + fn is_local(&self) -> bool { + guess_local_url(self.url.as_str()) + } + + fn get_transport<'a: 'b, 'b>( + &'a self, + ) -> alloy_transport::Pbf<'b, Self::Transport, TransportError> { + Box::pin(async move { + let hyper_t = HyperClient::new(); + + Ok(Http::with_client(hyper_t, self.url.clone())) + }) + } +} + +impl Service for Http> where - C: Connect + Clone + Send + Sync + 'static, - B: From + Buf + Send + 'static, + S: Service, Response = HyperResponse> + Clone + Send + Sync + 'static, + S::Future: Send, + S::Error: std::error::Error + Send + Sync + 'static, + B: From> + Send + 'static + Clone + Sync, { type Response = ResponsePacket; type Error = TransportError; type Future = TransportFut<'static>; - #[inline] fn poll_ready(&mut self, _cx: &mut task::Context<'_>) -> task::Poll> { - // hyper always returns ok task::Poll::Ready(Ok(())) } - #[inline] fn call(&mut self, req: RequestPacket) -> Self::Future { self.request_hyper(req) } } -impl Service for Http>> +impl Service for &Http> where - C: Connect + Clone + Send + Sync + 'static, - B: From + Buf + Send + 'static, + S: Service, Response = HyperResponse> + Clone + Send + Sync + 'static, + S::Future: Send, + S::Error: std::error::Error + Send + Sync + 'static, + B: From> + Send + 'static + Clone + Sync, { type Response = ResponsePacket; type Error = TransportError; type Future = TransportFut<'static>; - #[inline] fn poll_ready(&mut self, _cx: &mut task::Context<'_>) -> task::Poll> { - // hyper always returns ok task::Poll::Ready(Ok(())) } - #[inline] fn call(&mut self, req: RequestPacket) -> Self::Future { self.request_hyper(req) } diff --git a/crates/transport-http/src/lib.rs b/crates/transport-http/src/lib.rs index b12a048ce61..d1881fefaae 100644 --- a/crates/transport-http/src/lib.rs +++ b/crates/transport-http/src/lib.rs @@ -6,6 +6,8 @@ #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))] +#[cfg(feature = "reqwest")] +pub use reqwest; #[cfg(feature = "reqwest")] mod reqwest_transport; @@ -13,22 +15,20 @@ mod reqwest_transport; #[doc(inline)] pub use reqwest_transport::*; -#[cfg(feature = "reqwest")] -pub use reqwest; - #[cfg(all(not(target_arch = "wasm32"), feature = "hyper"))] -mod hyper_transport; +pub use hyper; #[cfg(all(not(target_arch = "wasm32"), feature = "hyper"))] -#[doc(inline)] -pub use hyper_transport::*; +pub use hyper_util; #[cfg(all(not(target_arch = "wasm32"), feature = "hyper"))] -pub use hyper; +mod hyper_transport; #[cfg(all(not(target_arch = "wasm32"), feature = "hyper"))] -pub use hyper_util; +#[doc(inline)] +pub use hyper_transport::{HyperClient, HyperResponse, HyperResponseFut, HyperTransport}; use alloy_transport::utils::guess_local_url; -use core::{marker::PhantomData, str::FromStr}; +use core::str::FromStr; +use std::marker::PhantomData; use url::Url; /// Connection details for an HTTP transport. @@ -37,6 +37,7 @@ use url::Url; pub struct HttpConnect { /// The URL to connect to. url: Url, + _pd: PhantomData, } From 79fe18216191b866a74a13fb720416c7d9df632f Mon Sep 17 00:00:00 2001 From: Roman Krasiuk Date: Wed, 18 Sep 2024 11:57:19 +0200 Subject: [PATCH 182/186] feat(rpc-types-beacon): `SignedBidSubmissionV4` (#1303) * feat(rpc-types-beacon): `SignedBidSubmissionV4` * ssz * Update crates/rpc-types-beacon/src/relay.rs Co-authored-by: Oliver --------- Co-authored-by: Matthias Seitz Co-authored-by: Oliver --- crates/eips/src/eip7002.rs | 1 + crates/rpc-types-beacon/src/relay.rs | 17 ++++ crates/rpc-types-engine/src/payload.rs | 112 +++++++++++++++++++++++++ 3 files changed, 130 insertions(+) diff --git a/crates/eips/src/eip7002.rs b/crates/eips/src/eip7002.rs index 43a11df5c06..fb3780337fe 100644 --- a/crates/eips/src/eip7002.rs +++ b/crates/eips/src/eip7002.rs @@ -25,6 +25,7 @@ pub const WITHDRAWAL_REQUEST_TYPE: u8 = 0x01; #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, RlpEncodable, RlpDecodable, Default)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] #[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] +#[cfg_attr(feature = "ssz", derive(ssz_derive::Encode, ssz_derive::Decode))] #[cfg_attr(any(test, feature = "arbitrary"), derive(arbitrary::Arbitrary))] pub struct WithdrawalRequest { /// Address of the source of the exit. diff --git a/crates/rpc-types-beacon/src/relay.rs b/crates/rpc-types-beacon/src/relay.rs index d15feb8e3a8..5b1b056843b 100644 --- a/crates/rpc-types-beacon/src/relay.rs +++ b/crates/rpc-types-beacon/src/relay.rs @@ -6,6 +6,7 @@ use crate::{BlsPublicKey, BlsSignature}; use alloy_primitives::{Address, B256, U256}; use alloy_rpc_types_engine::{ BlobsBundleV1, ExecutionPayload, ExecutionPayloadV1, ExecutionPayloadV2, ExecutionPayloadV3, + ExecutionPayloadV4, }; use serde::{Deserialize, Serialize}; use serde_with::{serde_as, DisplayFromStr}; @@ -139,6 +140,22 @@ pub struct SignedBidSubmissionV3 { pub signature: BlsSignature, } +/// Submission for the `/relay/v1/builder/blocks` endpoint (Electra). +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +#[cfg_attr(feature = "ssz", derive(ssz_derive::Decode, ssz_derive::Encode))] +pub struct SignedBidSubmissionV4 { + /// The [`BidTrace`] message associated with the submission. + pub message: BidTrace, + /// The execution payload for the submission. + #[serde(with = "crate::payload::beacon_payload_v4")] + pub execution_payload: ExecutionPayloadV4, + /// The Electra block bundle for this bid. + pub blobs_bundle: BlobsBundleV1, + /// The signature associated with the submission. + pub signature: BlsSignature, +} + /// SubmitBlockRequest is the request from the builder to submit a block. #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct SubmitBlockRequest { diff --git a/crates/rpc-types-engine/src/payload.rs b/crates/rpc-types-engine/src/payload.rs index 1d35a261594..93e37fb0291 100644 --- a/crates/rpc-types-engine/src/payload.rs +++ b/crates/rpc-types-engine/src/payload.rs @@ -476,6 +476,118 @@ impl ExecutionPayloadV4 { } } +#[cfg(feature = "ssz")] +impl ssz::Decode for ExecutionPayloadV4 { + fn is_ssz_fixed_len() -> bool { + false + } + + fn from_ssz_bytes(bytes: &[u8]) -> Result { + let mut builder = ssz::SszDecoderBuilder::new(bytes); + + builder.register_type::()?; + builder.register_type::
()?; + builder.register_type::()?; + builder.register_type::()?; + builder.register_type::()?; + builder.register_type::()?; + builder.register_type::()?; + builder.register_type::()?; + builder.register_type::()?; + builder.register_type::()?; + builder.register_type::()?; + builder.register_type::()?; + builder.register_type::()?; + builder.register_type::>()?; + builder.register_type::>()?; + builder.register_type::()?; + builder.register_type::()?; + builder.register_type::>()?; + builder.register_type::>()?; + builder.register_type::>()?; + + let mut decoder = builder.build()?; + + Ok(Self { + payload_inner: ExecutionPayloadV3 { + payload_inner: ExecutionPayloadV2 { + payload_inner: ExecutionPayloadV1 { + parent_hash: decoder.decode_next()?, + fee_recipient: decoder.decode_next()?, + state_root: decoder.decode_next()?, + receipts_root: decoder.decode_next()?, + logs_bloom: decoder.decode_next()?, + prev_randao: decoder.decode_next()?, + block_number: decoder.decode_next()?, + gas_limit: decoder.decode_next()?, + gas_used: decoder.decode_next()?, + timestamp: decoder.decode_next()?, + extra_data: decoder.decode_next()?, + base_fee_per_gas: decoder.decode_next()?, + block_hash: decoder.decode_next()?, + transactions: decoder.decode_next()?, + }, + withdrawals: decoder.decode_next()?, + }, + blob_gas_used: decoder.decode_next()?, + excess_blob_gas: decoder.decode_next()?, + }, + deposit_requests: decoder.decode_next()?, + withdrawal_requests: decoder.decode_next()?, + consolidation_requests: decoder.decode_next()?, + }) + } +} + +#[cfg(feature = "ssz")] +impl ssz::Encode for ExecutionPayloadV4 { + fn is_ssz_fixed_len() -> bool { + false + } + + fn ssz_append(&self, buf: &mut Vec) { + let offset = ::ssz_fixed_len() * 5 + +
::ssz_fixed_len() + + ::ssz_fixed_len() + + ::ssz_fixed_len() * 6 + + ::ssz_fixed_len() + + ssz::BYTES_PER_LENGTH_OFFSET * 6; + + let mut encoder = ssz::SszEncoder::container(buf, offset); + + encoder.append(&self.payload_inner.payload_inner.payload_inner.parent_hash); + encoder.append(&self.payload_inner.payload_inner.payload_inner.fee_recipient); + encoder.append(&self.payload_inner.payload_inner.payload_inner.state_root); + encoder.append(&self.payload_inner.payload_inner.payload_inner.receipts_root); + encoder.append(&self.payload_inner.payload_inner.payload_inner.logs_bloom); + encoder.append(&self.payload_inner.payload_inner.payload_inner.prev_randao); + encoder.append(&self.payload_inner.payload_inner.payload_inner.block_number); + encoder.append(&self.payload_inner.payload_inner.payload_inner.gas_limit); + encoder.append(&self.payload_inner.payload_inner.payload_inner.gas_used); + encoder.append(&self.payload_inner.payload_inner.payload_inner.timestamp); + encoder.append(&self.payload_inner.payload_inner.payload_inner.extra_data); + encoder.append(&self.payload_inner.payload_inner.payload_inner.base_fee_per_gas); + encoder.append(&self.payload_inner.payload_inner.payload_inner.block_hash); + encoder.append(&self.payload_inner.payload_inner.payload_inner.transactions); + encoder.append(&self.payload_inner.payload_inner.withdrawals); + encoder.append(&self.payload_inner.blob_gas_used); + encoder.append(&self.payload_inner.excess_blob_gas); + encoder.append(&self.deposit_requests); + encoder.append(&self.withdrawal_requests); + encoder.append(&self.consolidation_requests); + + encoder.finalize(); + } + + fn ssz_bytes_len(&self) -> usize { + ::ssz_bytes_len(&self.payload_inner) + + ssz::BYTES_PER_LENGTH_OFFSET * 3 + + self.deposit_requests.ssz_bytes_len() + + self.withdrawal_requests.ssz_bytes_len() + + self.consolidation_requests.ssz_bytes_len() + } +} + /// This includes all bundled blob related data of an executed payload. #[derive(Clone, Debug, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] From 6369bccbabb869492dff0dbf5a19a25601a50036 Mon Sep 17 00:00:00 2001 From: James Prestwich Date: Wed, 18 Sep 2024 06:06:41 -0400 Subject: [PATCH 183/186] feature: ProviderCall (#788) * feature: ProviderCall fix: rename to prov_call for disambiguation * refactor: replace output types * doc: add note about fn pointers * feat: convert `EthCall` to `ProviderCall` * use `ClientRef` in EthCall instead of `WeakClient` * change lifetimes * add *_internal methods that return `EthCall` * doc nits * use `ClientRef` instead of `WeakClient` in `RpcWithBlock` * Revert "use `ClientRef` instead of `WeakClient` in `RpcWithBlock`" This reverts commit 569d168d37dcb5b3e6449f997670799b2f02dd0a. * feat: RpcCallWithBlock enum val in provider call * nits * feat: integrate `RpcWithBlock` into `ProviderCall` * rm `RpcWithBlock` val from ProviderCall * feat(provider): caller trait for with_block calls * rm `WeakClient` from `RpcWithBlock` * introduce `Caller` into `RpcWithBlock` * use `WithBlockCall` in `RpcWithBlock`. polling doesn't work. * nit * feat(provider): add `WithBlockFut` - polls `ProviderCall` and maps response. * nit * revert 2ff402 * Revert "feat: convert `EthCall` to `ProviderCall`" This reverts commit 1cb1579b1d0c2c21c97e2fed7e26f0ada9d1f5ed. * doc nits * feat(provider): introduce `Caller` to `EthCall`. Arc it so that its cloneable * feat(provider): add `EthCaller` - converts EthCall into ProviderCall and strengthen test * update `EthCallFut` * holds `ProviderCall` * removes Clone * impl poll_preparing and poll_running on `EthCallFut` instead of `EthCallFutInner` * poll `ProviderCall` in `EthCall`using `EthCaller` * removes WeakClient from `EthCall` * updates `EthCallFutInner::Running` to store map * nit * wrap Caller in Arc to make `RpcWithBlock` cloneable * store in `ProvideCall` fut instance in `States` * store `ProviderCall` fut in `EthCallFutInner` * feat(provider): add `ParamsWithBlock` for `RpcWithBlock` * rm `block_id` from `Caller` trait * impl `Caller` for `WeakClient` * refactor(`ProviderCall`): don't rely on `Caller` in `RpcWithBlock` (#1159) * feat: RpcCall:map_params * WithBlockInner * Ready variant * fmt * use ProviderCall * clippy + fmt * add From * make ProviderCall::Ready return a result * add docs * Update request.rs Co-authored-by: DaniPopes <57450786+DaniPopes@users.noreply.github.com> * fmt --------- Co-authored-by: DaniPopes <57450786+DaniPopes@users.noreply.github.com> * refac(provider): use `ProviderCall` as return in trait * nit * doc nits * fix --------- Co-authored-by: Yash Atreya <44857776+yash-atreya@users.noreply.github.com> Co-authored-by: Arsenii Kulikov Co-authored-by: DaniPopes <57450786+DaniPopes@users.noreply.github.com> --- crates/contract/src/call.rs | 4 +- crates/contract/src/eth_call.rs | 38 ++- crates/json-rpc/src/request.rs | 15 +- crates/provider/src/ext/trace.rs | 4 +- crates/provider/src/lib.rs | 11 +- crates/provider/src/provider/caller.rs | 47 +++ .../src/provider/{call.rs => eth_call.rs} | 187 +++++++----- crates/provider/src/provider/mod.rs | 12 +- crates/provider/src/provider/prov_call.rs | 268 ++++++++++++++++++ crates/provider/src/provider/trait.rs | 161 +++++++---- crates/provider/src/provider/with_block.rs | 266 ++++++----------- crates/rpc-client/src/batch.rs | 58 +++- crates/rpc-client/src/call.rs | 65 +++-- 13 files changed, 770 insertions(+), 366 deletions(-) create mode 100644 crates/provider/src/provider/caller.rs rename crates/provider/src/provider/{call.rs => eth_call.rs} (61%) create mode 100644 crates/provider/src/provider/prov_call.rs diff --git a/crates/contract/src/call.rs b/crates/contract/src/call.rs index c7d164e6acb..1d1f0a38171 100644 --- a/crates/contract/src/call.rs +++ b/crates/contract/src/call.rs @@ -447,7 +447,7 @@ impl, D: CallDecoder, N: Network> CallBu /// If this is not desired, use [`call_raw`](Self::call_raw) to get the raw output data. #[doc(alias = "eth_call")] #[doc(alias = "call_with_overrides")] - pub fn call(&self) -> EthCall<'_, '_, '_, D, T, N> { + pub fn call(&self) -> EthCall<'_, '_, D, T, N> { self.call_raw().with_decoder(&self.decoder) } @@ -457,7 +457,7 @@ impl, D: CallDecoder, N: Network> CallBu /// Does not decode the output of the call, returning the raw output data instead. /// /// See [`call`](Self::call) for more information. - pub fn call_raw(&self) -> EthCall<'_, '_, '_, (), T, N> { + pub fn call_raw(&self) -> EthCall<'_, '_, (), T, N> { let call = self.provider.call(&self.request).block(self.block); let call = match &self.state { Some(state) => call.overrides(state), diff --git a/crates/contract/src/eth_call.rs b/crates/contract/src/eth_call.rs index c4dd8c227bb..2f4e9db089c 100644 --- a/crates/contract/src/eth_call.rs +++ b/crates/contract/src/eth_call.rs @@ -24,18 +24,18 @@ mod private { /// An [`alloy_provider::EthCall`] with an abi decoder. #[must_use = "EthCall must be awaited to execute the call"] #[derive(Clone, Debug)] -pub struct EthCall<'req, 'state, 'coder, D, T, N> +pub struct EthCall<'req, 'coder, D, T, N> where T: Transport + Clone, N: Network, D: CallDecoder, { - inner: alloy_provider::EthCall<'req, 'state, T, N, Bytes>, + inner: alloy_provider::EthCall<'req, T, N, Bytes>, decoder: &'coder D, } -impl<'req, 'state, 'coder, D, T, N> EthCall<'req, 'state, 'coder, D, T, N> +impl<'req, 'coder, D, T, N> EthCall<'req, 'coder, D, T, N> where T: Transport + Clone, N: Network, @@ -43,25 +43,25 @@ where { /// Create a new [`EthCall`]. pub const fn new( - inner: alloy_provider::EthCall<'req, 'state, T, N, Bytes>, + inner: alloy_provider::EthCall<'req, T, N, Bytes>, decoder: &'coder D, ) -> Self { Self { inner, decoder } } } -impl<'req, 'state, T, N> EthCall<'req, 'state, 'static, (), T, N> +impl<'req, T, N> EthCall<'req, 'static, (), T, N> where T: Transport + Clone, N: Network, { /// Create a new [`EthCall`]. - pub const fn new_raw(inner: alloy_provider::EthCall<'req, 'state, T, N, Bytes>) -> Self { + pub const fn new_raw(inner: alloy_provider::EthCall<'req, T, N, Bytes>) -> Self { Self::new(inner, &RAW_CODER) } } -impl<'req, 'state, 'coder, D, T, N> EthCall<'req, 'state, 'coder, D, T, N> +impl<'req, 'coder, D, T, N> EthCall<'req, 'coder, D, T, N> where T: Transport + Clone, N: Network, @@ -71,7 +71,7 @@ where pub fn with_decoder<'new_coder, E>( self, decoder: &'new_coder E, - ) -> EthCall<'req, 'state, 'new_coder, E, T, N> + ) -> EthCall<'req, 'new_coder, E, T, N> where E: CallDecoder, { @@ -79,7 +79,7 @@ where } /// Set the state overrides for this call. - pub fn overrides(mut self, overrides: &'state StateOverride) -> Self { + pub fn overrides(mut self, overrides: &'req StateOverride) -> Self { self.inner = self.inner.overrides(overrides); self } @@ -91,19 +91,18 @@ where } } -impl<'req, 'state, T, N> From> - for EthCall<'req, 'state, 'static, (), T, N> +impl<'req, T, N> From> + for EthCall<'req, 'static, (), T, N> where T: Transport + Clone, N: Network, { - fn from(inner: alloy_provider::EthCall<'req, 'state, T, N, Bytes>) -> Self { + fn from(inner: alloy_provider::EthCall<'req, T, N, Bytes>) -> Self { Self { inner, decoder: &RAW_CODER } } } -impl<'req, 'state, 'coder, D, T, N> std::future::IntoFuture - for EthCall<'req, 'state, 'coder, D, T, N> +impl<'req, 'coder, D, T, N> std::future::IntoFuture for EthCall<'req, 'coder, D, T, N> where D: CallDecoder + Unpin, T: Transport + Clone, @@ -111,7 +110,7 @@ where { type Output = Result; - type IntoFuture = EthCallFut<'req, 'state, 'coder, D, T, N>; + type IntoFuture = EthCallFut<'req, 'coder, D, T, N>; fn into_future(self) -> Self::IntoFuture { EthCallFut { inner: self.inner.into_future(), decoder: self.decoder } @@ -121,20 +120,19 @@ where /// Future for the [`EthCall`] type. This future wraps an RPC call with an abi /// decoder. #[must_use = "futures do nothing unless you `.await` or poll them"] -#[derive(Clone, Debug)] +#[derive(Debug)] #[allow(unnameable_types)] -pub struct EthCallFut<'req, 'state, 'coder, D, T, N> +pub struct EthCallFut<'req, 'coder, D, T, N> where T: Transport + Clone, N: Network, D: CallDecoder, { - inner: as IntoFuture>::IntoFuture, + inner: as IntoFuture>::IntoFuture, decoder: &'coder D, } -impl<'req, 'state, 'coder, D, T, N> std::future::Future - for EthCallFut<'req, 'state, 'coder, D, T, N> +impl<'req, 'coder, D, T, N> std::future::Future for EthCallFut<'req, 'coder, D, T, N> where D: CallDecoder + Unpin, T: Transport + Clone, diff --git a/crates/json-rpc/src/request.rs b/crates/json-rpc/src/request.rs index bc8fb11b4e7..2dac9b67092 100644 --- a/crates/json-rpc/src/request.rs +++ b/crates/json-rpc/src/request.rs @@ -78,6 +78,14 @@ impl Request { pub fn set_subscription_status(&mut self, sub: bool) { self.meta.set_subscription_status(sub); } + + /// Change type of the request parameters. + pub fn map_params( + self, + map: impl FnOnce(Params) -> NewParams, + ) -> Request { + Request { meta: self.meta, params: map(self.params) } + } } /// A [`Request`] that has been partially serialized. @@ -113,11 +121,12 @@ where impl Request<&Params> where - Params: Clone, + Params: ToOwned, + Params::Owned: RpcParam, { /// Clone the request, including the request parameters. - pub fn into_owned_params(self) -> Request { - Request { meta: self.meta, params: self.params.clone() } + pub fn into_owned_params(self) -> Request { + Request { meta: self.meta, params: self.params.to_owned() } } } diff --git a/crates/provider/src/ext/trace.rs b/crates/provider/src/ext/trace.rs index a0b748b5a9c..58944e8963d 100644 --- a/crates/provider/src/ext/trace.rs +++ b/crates/provider/src/ext/trace.rs @@ -112,14 +112,14 @@ where trace_types: &'b [TraceType], ) -> RpcWithBlock::TransactionRequest, &'b [TraceType]), TraceResults> { - RpcWithBlock::new(self.weak_client(), "trace_call", (request, trace_types)) + self.client().request("trace_call", (request, trace_types)).into() } fn trace_call_many<'a>( &self, request: TraceCallList<'a, N>, ) -> RpcWithBlock,), Vec> { - RpcWithBlock::new(self.weak_client(), "trace_callMany", (request,)) + self.client().request("trace_callMany", (request,)).into() } async fn trace_transaction( diff --git a/crates/provider/src/lib.rs b/crates/provider/src/lib.rs index a59bdc8c0fb..9105f58e530 100644 --- a/crates/provider/src/lib.rs +++ b/crates/provider/src/lib.rs @@ -28,12 +28,11 @@ extern crate tracing; mod builder; pub use builder::{Identity, ProviderBuilder, ProviderLayer, Stack}; +mod chain; + pub mod ext; pub mod fillers; -pub mod layers; - -mod chain; mod heart; pub use heart::{ @@ -41,10 +40,12 @@ pub use heart::{ PendingTransactionError, WatchTxError, }; +pub mod layers; + mod provider; pub use provider::{ - builder, EthCall, FilterPollerBuilder, Provider, RootProvider, RpcWithBlock, SendableTx, - WalletProvider, + builder, Caller, EthCall, EthCallParams, FilterPollerBuilder, ParamsWithBlock, Provider, + ProviderCall, RootProvider, RpcWithBlock, SendableTx, WalletProvider, }; pub mod utils; diff --git a/crates/provider/src/provider/caller.rs b/crates/provider/src/provider/caller.rs new file mode 100644 index 00000000000..abd6db8c565 --- /dev/null +++ b/crates/provider/src/provider/caller.rs @@ -0,0 +1,47 @@ +use crate::ProviderCall; +use alloy_json_rpc::{RpcParam, RpcReturn}; +use alloy_rpc_client::WeakClient; +use alloy_transport::{RpcError, Transport, TransportErrorKind, TransportResult}; +use std::borrow::Cow; + +// TODO: Make `EthCall` specific. Ref: https://github.com/alloy-rs/alloy/pull/788#discussion_r1748862509. + +/// Trait that helpes convert `EthCall` into a `ProviderCall`. +pub trait Caller: Send + Sync +where + T: Transport + Clone, + Params: RpcParam, + Resp: RpcReturn, +{ + /// Method that needs to be implemented to convert to a `ProviderCall`. + /// + /// This method handles serialization of the params and sends the request to relevant data + /// source and returns a `ProviderCall`. + fn call( + &self, + method: Cow<'static, str>, + params: Params, + ) -> TransportResult>; +} + +impl Caller for WeakClient +where + T: Transport + Clone, + Params: RpcParam, + Resp: RpcReturn, +{ + fn call( + &self, + method: Cow<'static, str>, + params: Params, + ) -> TransportResult> { + let client = self.upgrade().ok_or_else(TransportErrorKind::backend_gone)?; + + // serialize the params + let ser = serde_json::to_value(params).map_err(RpcError::ser_err)?; + + let rpc_call = client.request(method, ser); + + Ok(ProviderCall::RpcCall(rpc_call)) + } +} diff --git a/crates/provider/src/provider/call.rs b/crates/provider/src/provider/eth_call.rs similarity index 61% rename from crates/provider/src/provider/call.rs rename to crates/provider/src/provider/eth_call.rs index c79d3944c36..83433490568 100644 --- a/crates/provider/src/provider/call.rs +++ b/crates/provider/src/provider/eth_call.rs @@ -1,24 +1,23 @@ use alloy_eips::BlockId; use alloy_json_rpc::RpcReturn; use alloy_network::Network; -use alloy_rpc_client::{RpcCall, WeakClient}; use alloy_rpc_types_eth::state::StateOverride; -use alloy_transport::{Transport, TransportErrorKind, TransportResult}; +use alloy_transport::{Transport, TransportResult}; use futures::FutureExt; use serde::ser::SerializeSeq; -use std::{future::Future, marker::PhantomData, task::Poll}; +use std::{future::Future, marker::PhantomData, sync::Arc, task::Poll}; -type RunningFut<'req, 'state, T, N, Resp, Output, Map> = - RpcCall, Resp, Output, Map>; +use crate::{Caller, ProviderCall}; +/// The parameters for an `"eth_call"` RPC request. #[derive(Clone, Debug)] -struct EthCallParams<'req, 'state, N: Network> { +pub struct EthCallParams<'req, N: Network> { data: &'req N::TransactionRequest, block: Option, - overrides: Option<&'state StateOverride>, + overrides: Option<&'req StateOverride>, } -impl serde::Serialize for EthCallParams<'_, '_, N> { +impl serde::Serialize for EthCallParams<'_, N> { fn serialize(&self, serializer: S) -> Result { let len = if self.overrides.is_some() { 3 } else { 2 }; @@ -37,21 +36,22 @@ impl serde::Serialize for EthCallParams<'_, '_, N> { } /// The [`EthCallFut`] future is the future type for an `eth_call` RPC request. -#[derive(Clone, Debug)] +#[derive(Debug)] #[doc(hidden)] // Not public API. #[allow(unnameable_types)] #[pin_project::pin_project] -pub struct EthCallFut<'req, 'state, T, N, Resp, Output, Map>( - EthCallFutInner<'req, 'state, T, N, Resp, Output, Map>, -) +pub struct EthCallFut<'req, T, N, Resp, Output, Map> where T: Transport + Clone, N: Network, Resp: RpcReturn, - Map: Fn(Resp) -> Output; + Output: 'static, + Map: Fn(Resp) -> Output, +{ + inner: EthCallFutInner<'req, T, N, Resp, Output, Map>, +} -#[derive(Clone, Debug)] -enum EthCallFutInner<'req, 'state, T, N, Resp, Output, Map> +enum EthCallFutInner<'req, T, N, Resp, Output, Map> where T: Transport + Clone, N: Network, @@ -59,18 +59,45 @@ where Map: Fn(Resp) -> Output, { Preparing { - client: WeakClient, + caller: Arc, Resp>>, data: &'req N::TransactionRequest, - overrides: Option<&'state StateOverride>, + overrides: Option<&'req StateOverride>, block: Option, method: &'static str, map: Map, }, - Running(RunningFut<'req, 'state, T, N, Resp, Output, Map>), + Running { + map: Map, + fut: ProviderCall, + }, Polling, } -impl<'req, 'state, T, N, Resp, Output, Map> EthCallFutInner<'req, 'state, T, N, Resp, Output, Map> +impl<'req, T, N, Resp, Output, Map> core::fmt::Debug + for EthCallFutInner<'req, T, N, Resp, Output, Map> +where + T: Transport + Clone, + N: Network, + Resp: RpcReturn, + Output: 'static, + Map: Fn(Resp) -> Output, +{ + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + match self { + Self::Preparing { caller: _, data, overrides, block, method, map: _ } => f + .debug_struct("Preparing") + .field("data", data) + .field("overrides", overrides) + .field("block", block) + .field("method", method) + .finish(), + Self::Running { .. } => f.debug_tuple("Running").finish(), + Self::Polling => f.debug_tuple("Polling").finish(), + } + } +} + +impl<'req, T, N, Resp, Output, Map> EthCallFut<'req, T, N, Resp, Output, Map> where T: Transport + Clone, N: Network, @@ -80,43 +107,40 @@ where { /// Returns `true` if the future is in the preparing state. const fn is_preparing(&self) -> bool { - matches!(self, Self::Preparing { .. }) + matches!(self.inner, EthCallFutInner::Preparing { .. }) } /// Returns `true` if the future is in the running state. const fn is_running(&self) -> bool { - matches!(self, Self::Running(..)) + matches!(self.inner, EthCallFutInner::Running { .. }) } fn poll_preparing(&mut self, cx: &mut std::task::Context<'_>) -> Poll> { - let Self::Preparing { client, data, overrides, block, method, map } = - std::mem::replace(self, Self::Polling) + let EthCallFutInner::Preparing { caller, data, overrides, block, method, map } = + std::mem::replace(&mut self.inner, EthCallFutInner::Polling) else { unreachable!("bad state") }; - let client = match client.upgrade().ok_or_else(TransportErrorKind::backend_gone) { - Ok(client) => client, - Err(e) => return Poll::Ready(Err(e)), - }; - let params = EthCallParams { data, block, overrides }; - let fut = client.request(method, params).map_resp(map); + let fut = caller.call(method.into(), params)?; + + self.inner = EthCallFutInner::Running { map, fut }; - *self = Self::Running(fut); self.poll_running(cx) } fn poll_running(&mut self, cx: &mut std::task::Context<'_>) -> Poll> { - let Self::Running(ref mut call) = self else { unreachable!("bad state") }; + let EthCallFutInner::Running { ref map, ref mut fut } = self.inner else { + unreachable!("bad state") + }; - call.poll_unpin(cx) + fut.poll_unpin(cx).map(|res| res.map(map)) } } -impl<'req, 'state, T, N, Resp, Output, Map> Future - for EthCallFut<'req, 'state, T, N, Resp, Output, Map> +impl<'req, T, N, Resp, Output, Map> Future for EthCallFut<'req, T, N, Resp, Output, Map> where T: Transport + Clone, N: Network, @@ -130,7 +154,7 @@ where self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<'_>, ) -> std::task::Poll { - let this = &mut self.get_mut().0; + let this = self.get_mut(); if this.is_preparing() { this.poll_preparing(cx) } else if this.is_running() { @@ -146,34 +170,52 @@ where /// /// [`Provider::call`]: crate::Provider::call #[must_use = "EthCall must be awaited to execute the call"] -#[derive(Debug, Clone)] -pub struct EthCall<'req, 'state, T, N, Resp, Output = Resp, Map = fn(Resp) -> Output> +#[derive(Clone)] +pub struct EthCall<'req, T, N, Resp, Output = Resp, Map = fn(Resp) -> Output> where T: Transport + Clone, N: Network, Resp: RpcReturn, Map: Fn(Resp) -> Output, { - client: WeakClient, - + caller: Arc, Resp>>, data: &'req N::TransactionRequest, - overrides: Option<&'state StateOverride>, + overrides: Option<&'req StateOverride>, block: Option, method: &'static str, map: Map, _pd: PhantomData (Resp, Output)>, } -impl<'req, T, N, Resp> EthCall<'req, 'static, T, N, Resp> +impl<'req, T, N, Resp> core::fmt::Debug for EthCall<'req, T, N, Resp> +where + T: Transport + Clone, + N: Network, + Resp: RpcReturn, +{ + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.debug_struct("EthCall") + .field("method", &self.method) + .field("data", &self.data) + .field("block", &self.block) + .field("overrides", &self.overrides) + .finish() + } +} + +impl<'req, T, N, Resp> EthCall<'req, T, N, Resp> where T: Transport + Clone, N: Network, Resp: RpcReturn, { /// Create a new CallBuilder. - pub const fn new(client: WeakClient, data: &'req N::TransactionRequest) -> Self { + pub fn new( + caller: impl Caller, Resp> + 'static, + data: &'req N::TransactionRequest, + ) -> Self { Self { - client, + caller: Arc::new(caller), data, overrides: None, block: None, @@ -184,9 +226,12 @@ where } /// Create new EthCall for gas estimates. - pub const fn gas_estimate(client: WeakClient, data: &'req N::TransactionRequest) -> Self { + pub fn gas_estimate( + caller: impl Caller, Resp> + 'static, + data: &'req N::TransactionRequest, + ) -> Self { Self { - client, + caller: Arc::new(caller), data, overrides: None, block: None, @@ -197,23 +242,33 @@ where } } -impl<'req, 'state, T, N, Resp, Output, Map> EthCall<'req, 'state, T, N, Resp, Output, Map> +impl<'req, T, N, Resp, Output, Map> EthCall<'req, T, N, Resp, Output, Map> where T: Transport + Clone, N: Network, Resp: RpcReturn, Map: Fn(Resp) -> Output, { - /// Map the response to a different type. + /// Map the response to a different type. This is usable for converting + /// the response to a more usable type, e.g. changing `U64` to `u64`. + /// + /// ## Note + /// + /// Carefully review the rust documentation on [fn pointers] before passing + /// them to this function. Unless the pointer is specifically coerced to a + /// `fn(_) -> _`, the `NewMap` will be inferred as that function's unique + /// type. This can lead to confusing error messages. + /// + /// [fn pointers]: https://doc.rust-lang.org/std/primitive.fn.html#creating-function-pointers pub fn map_resp( self, map: NewMap, - ) -> EthCall<'req, 'state, T, N, Resp, NewOutput, NewMap> + ) -> EthCall<'req, T, N, Resp, NewOutput, NewMap> where NewMap: Fn(Resp) -> NewOutput, { EthCall { - client: self.client, + caller: self.caller, data: self.data, overrides: self.overrides, block: self.block, @@ -224,7 +279,7 @@ where } /// Set the state overrides for this call. - pub const fn overrides(mut self, overrides: &'state StateOverride) -> Self { + pub const fn overrides(mut self, overrides: &'req StateOverride) -> Self { self.overrides = Some(overrides); self } @@ -236,8 +291,8 @@ where } } -impl<'req, 'state, T, N, Resp, Output, Map> std::future::IntoFuture - for EthCall<'req, 'state, T, N, Resp, Output, Map> +impl<'req, T, N, Resp, Output, Map> std::future::IntoFuture + for EthCall<'req, T, N, Resp, Output, Map> where T: Transport + Clone, N: Network, @@ -247,17 +302,19 @@ where { type Output = TransportResult; - type IntoFuture = EthCallFut<'req, 'state, T, N, Resp, Output, Map>; + type IntoFuture = EthCallFut<'req, T, N, Resp, Output, Map>; fn into_future(self) -> Self::IntoFuture { - EthCallFut(EthCallFutInner::Preparing { - client: self.client, - data: self.data, - overrides: self.overrides, - block: self.block, - method: self.method, - map: self.map, - }) + EthCallFut { + inner: EthCallFutInner::Preparing { + caller: self.caller, + data: self.data, + overrides: self.overrides, + block: self.block, + method: self.method, + map: self.map, + }, + } } } @@ -288,7 +345,7 @@ mod test { let overrides = StateOverride::default(); // Expected: [data] - let params: EthCallParams<'_, '_, Ethereum> = + let params: EthCallParams<'_, Ethereum> = EthCallParams { data: &data, block: None, overrides: None }; assert_eq!(params.data, &data); @@ -300,7 +357,7 @@ mod test { ); // Expected: [data, block, overrides] - let params: EthCallParams<'_, '_, Ethereum> = + let params: EthCallParams<'_, Ethereum> = EthCallParams { data: &data, block: Some(block), overrides: Some(&overrides) }; assert_eq!(params.data, &data); @@ -312,7 +369,7 @@ mod test { ); // Expected: [data, (default), overrides] - let params: EthCallParams<'_, '_, Ethereum> = + let params: EthCallParams<'_, Ethereum> = EthCallParams { data: &data, block: None, overrides: Some(&overrides) }; assert_eq!(params.data, &data); @@ -324,7 +381,7 @@ mod test { ); // Expected: [data, block] - let params: EthCallParams<'_, '_, Ethereum> = + let params: EthCallParams<'_, Ethereum> = EthCallParams { data: &data, block: Some(block), overrides: None }; assert_eq!(params.data, &data); diff --git a/crates/provider/src/provider/mod.rs b/crates/provider/src/provider/mod.rs index 0d8e939ed5a..8cd167497e6 100644 --- a/crates/provider/src/provider/mod.rs +++ b/crates/provider/src/provider/mod.rs @@ -1,5 +1,8 @@ -mod call; -pub use call::EthCall; +mod eth_call; +pub use eth_call::{EthCall, EthCallParams}; + +mod prov_call; +pub use prov_call::ProviderCall; mod root; pub use root::{builder, RootProvider}; @@ -14,4 +17,7 @@ mod wallet; pub use wallet::WalletProvider; mod with_block; -pub use with_block::RpcWithBlock; +pub use with_block::{ParamsWithBlock, RpcWithBlock}; + +mod caller; +pub use caller::Caller; diff --git a/crates/provider/src/provider/prov_call.rs b/crates/provider/src/provider/prov_call.rs new file mode 100644 index 00000000000..8e6b9f6119d --- /dev/null +++ b/crates/provider/src/provider/prov_call.rs @@ -0,0 +1,268 @@ +use alloy_json_rpc::{RpcParam, RpcReturn}; +use alloy_rpc_client::{RpcCall, Waiter}; +use alloy_transport::{Transport, TransportResult}; +use futures::FutureExt; +use pin_project::pin_project; +use serde_json::value::RawValue; +use std::{ + future::Future, + pin::Pin, + task::{self, Poll}, +}; +use tokio::sync::oneshot; + +/// The primary future type for the [`Provider`]. +/// +/// This future abstracts over several potential data sources. It allows +/// providers to: +/// - produce data via an [`RpcCall`] +/// - produce data by waiting on a batched RPC [`Waiter`] +/// - proudce data via an arbitrary boxed future +/// - produce data in any synchronous way +/// +/// [`Provider`]: crate::Provider +#[pin_project(project = ProviderCallProj)] +pub enum ProviderCall Output> +where + Conn: Transport + Clone, + Params: RpcParam, + Resp: RpcReturn, + Map: Fn(Resp) -> Output, +{ + /// An underlying call to an RPC server. + RpcCall(RpcCall), + /// A waiter for a batched call to a remote RPC server. + Waiter(Waiter), + /// A boxed future. + BoxedFuture(Pin> + Send>>), + /// The output, produces synchronously. + Ready(Option>), +} + +impl ProviderCall +where + Conn: Transport + Clone, + Params: RpcParam, + Resp: RpcReturn, + Map: Fn(Resp) -> Output, +{ + /// Instantiate a new [`ProviderCall`] from the output. + pub const fn ready(output: TransportResult) -> Self { + Self::Ready(Some(output)) + } + + /// True if this is an RPC call. + pub const fn is_rpc_call(&self) -> bool { + matches!(self, Self::RpcCall(_)) + } + + /// Fallible cast to [`RpcCall`] + pub const fn as_rpc_call(&self) -> Option<&RpcCall> { + match self { + Self::RpcCall(call) => Some(call), + _ => None, + } + } + + /// Fallible cast to mutable [`RpcCall`] + pub fn as_mut_rpc_call(&mut self) -> Option<&mut RpcCall> { + match self { + Self::RpcCall(call) => Some(call), + _ => None, + } + } + + /// True if this is a waiter. + pub const fn is_waiter(&self) -> bool { + matches!(self, Self::Waiter(_)) + } + + /// Fallible cast to [`Waiter`] + pub const fn as_waiter(&self) -> Option<&Waiter> { + match self { + Self::Waiter(waiter) => Some(waiter), + _ => None, + } + } + + /// Fallible cast to mutable [`Waiter`] + pub fn as_mut_waiter(&mut self) -> Option<&mut Waiter> { + match self { + Self::Waiter(waiter) => Some(waiter), + _ => None, + } + } + + /// True if this is a boxed future. + pub const fn is_boxed_future(&self) -> bool { + matches!(self, Self::BoxedFuture(_)) + } + + /// Fallible cast to a boxed future. + pub const fn as_boxed_future( + &self, + ) -> Option<&Pin> + Send>>> { + match self { + Self::BoxedFuture(fut) => Some(fut), + _ => None, + } + } + + /// True if this is a ready value. + pub const fn is_ready(&self) -> bool { + matches!(self, Self::Ready(_)) + } + + /// Fallible cast to a ready value. + /// + /// # Panics + /// + /// Panics if the future is already complete + pub const fn as_ready(&self) -> Option<&TransportResult> { + match self { + Self::Ready(Some(output)) => Some(output), + Self::Ready(None) => panic!("tried to access ready value after taking"), + _ => None, + } + } + + /// Set a function to map the response into a different type. This is + /// useful for transforming the response into a more usable type, e.g. + /// changing `U64` to `u64`. + /// + /// This function fails if the inner future is not an [`RpcCall`] or + /// [`Waiter`]. + /// + /// ## Note + /// + /// Carefully review the rust documentation on [fn pointers] before passing + /// them to this function. Unless the pointer is specifically coerced to a + /// `fn(_) -> _`, the `NewMap` will be inferred as that function's unique + /// type. This can lead to confusing error messages. + /// + /// [fn pointers]: https://doc.rust-lang.org/std/primitive.fn.html#creating-function-pointers + pub fn map_resp( + self, + map: NewMap, + ) -> Result, Self> + where + NewMap: Fn(Resp) -> NewOutput + Clone, + { + match self { + Self::RpcCall(call) => Ok(ProviderCall::RpcCall(call.map_resp(map))), + Self::Waiter(waiter) => Ok(ProviderCall::Waiter(waiter.map_resp(map))), + _ => Err(self), + } + } +} + +impl ProviderCall +where + Conn: Transport + Clone, + Params: RpcParam, + Params: ToOwned, + Params::Owned: RpcParam, + Resp: RpcReturn, + Map: Fn(Resp) -> Output, +{ + /// Convert this call into one with owned params, by cloning the params. + /// + /// # Panics + /// + /// Panics if called after the request has been polled. + pub fn into_owned_params(self) -> ProviderCall { + match self { + Self::RpcCall(call) => ProviderCall::RpcCall(call.into_owned_params()), + _ => panic!(), + } + } +} + +impl std::fmt::Debug for ProviderCall +where + Conn: Transport + Clone, + Params: RpcParam, + Resp: RpcReturn, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Self::RpcCall(call) => f.debug_tuple("RpcCall").field(call).finish(), + Self::Waiter { .. } => f.debug_struct("Waiter").finish_non_exhaustive(), + Self::BoxedFuture(_) => f.debug_struct("BoxedFuture").finish_non_exhaustive(), + Self::Ready(_) => f.debug_struct("Ready").finish_non_exhaustive(), + } + } +} + +impl From> + for ProviderCall +where + Conn: Transport + Clone, + Params: RpcParam, + Resp: RpcReturn, + Map: Fn(Resp) -> Output, +{ + fn from(call: RpcCall) -> Self { + Self::RpcCall(call) + } +} + +impl From> + for ProviderCall Resp> +where + Conn: Transport + Clone, + Params: RpcParam, + Resp: RpcReturn, +{ + fn from(waiter: Waiter) -> Self { + Self::Waiter(waiter) + } +} + +impl + From> + Send>>> + for ProviderCall +where + Conn: Transport + Clone, + Params: RpcParam, + Resp: RpcReturn, + Map: Fn(Resp) -> Output, +{ + fn from(fut: Pin> + Send>>) -> Self { + Self::BoxedFuture(fut) + } +} + +impl From>>> + for ProviderCall +where + Conn: Transport + Clone, + Params: RpcParam, + Resp: RpcReturn, +{ + fn from(rx: oneshot::Receiver>>) -> Self { + Waiter::from(rx).into() + } +} + +impl Future for ProviderCall +where + Conn: Transport + Clone, + Params: RpcParam, + Resp: RpcReturn, + Output: 'static, + Map: Fn(Resp) -> Output, +{ + type Output = TransportResult; + + fn poll(mut self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> task::Poll { + match self.as_mut().project() { + ProviderCallProj::RpcCall(call) => call.poll_unpin(cx), + ProviderCallProj::Waiter(waiter) => waiter.poll_unpin(cx), + ProviderCallProj::BoxedFuture(fut) => fut.poll_unpin(cx), + ProviderCallProj::Ready(output) => { + Poll::Ready(output.take().expect("output taken twice")) + } + } + } +} diff --git a/crates/provider/src/provider/trait.rs b/crates/provider/src/provider/trait.rs index c522c8a3799..d04fa821786 100644 --- a/crates/provider/src/provider/trait.rs +++ b/crates/provider/src/provider/trait.rs @@ -1,10 +1,9 @@ //! Ethereum JSON-RPC provider. - use crate::{ heart::PendingTransactionError, utils::{self, Eip1559Estimation, EstimatorFunction}, EthCall, Identity, PendingTransaction, PendingTransactionBuilder, PendingTransactionConfig, - ProviderBuilder, RootProvider, RpcWithBlock, SendableTx, + ProviderBuilder, ProviderCall, RootProvider, RpcWithBlock, SendableTx, }; use alloy_eips::eip2718::Encodable2718; use alloy_json_rpc::{RpcError, RpcParam, RpcReturn}; @@ -16,7 +15,7 @@ use alloy_primitives::{ hex, Address, BlockHash, BlockNumber, Bytes, StorageKey, StorageValue, TxHash, B256, U128, U256, U64, }; -use alloy_rpc_client::{ClientRef, NoParams, PollerBuilder, RpcCall, WeakClient}; +use alloy_rpc_client::{ClientRef, NoParams, PollerBuilder, WeakClient}; use alloy_rpc_types_eth::{ AccessListResult, BlockId, BlockNumberOrTag, EIP1186AccountProofResponse, FeeHistory, Filter, FilterChanges, Log, SyncStatus, @@ -100,18 +99,24 @@ pub trait Provider: /// Gets the accounts in the remote node. This is usually empty unless you're using a local /// node. - async fn get_accounts(&self) -> TransportResult> { - self.client().request_noparams("eth_accounts").await + fn get_accounts(&self) -> ProviderCall> { + self.client().request_noparams("eth_accounts").into() } /// Returns the base fee per blob gas (blob gas price) in wei. - async fn get_blob_base_fee(&self) -> TransportResult { - self.client().request_noparams("eth_blobBaseFee").await.map(|fee: U128| fee.to::()) + fn get_blob_base_fee(&self) -> ProviderCall { + self.client() + .request_noparams("eth_blobBaseFee") + .map_resp(utils::convert_u128 as fn(U128) -> u128) + .into() } /// Get the last block number available. - fn get_block_number(&self) -> RpcCall { - self.client().request_noparams("eth_blockNumber").map_resp(crate::utils::convert_u64) + fn get_block_number(&self) -> ProviderCall { + self.client() + .request_noparams("eth_blockNumber") + .map_resp(crate::utils::convert_u64 as fn(U64) -> u64) + .into() } /// Execute a smart contract call with a transaction request and state @@ -138,29 +143,21 @@ pub trait Provider: /// # let tx = alloy_rpc_types_eth::transaction::TransactionRequest::default(); /// // Execute a call on the latest block, with no state overrides /// let output = provider.call(&tx).await?; - /// // Execute a call with a block ID. - /// let output = provider.call(&tx).block(1.into()).await?; - /// // Execute a call with state overrides. - /// let output = provider.call(&tx).overrides(&my_overrides).await?; /// # Ok(()) /// # } /// ``` - /// - /// # Note - /// - /// Not all client implementations support state overrides. #[doc(alias = "eth_call")] #[doc(alias = "call_with_overrides")] - fn call<'req, 'state>( - &self, - tx: &'req N::TransactionRequest, - ) -> EthCall<'req, 'state, T, N, Bytes> { + fn call<'req>(&self, tx: &'req N::TransactionRequest) -> EthCall<'req, T, N, Bytes> { EthCall::new(self.weak_client(), tx) } - /// Gets the chain ID. - fn get_chain_id(&self) -> RpcCall { - self.client().request_noparams("eth_chainId").map_resp(crate::utils::convert_u64) + /// Gets the chain ID. + fn get_chain_id(&self) -> ProviderCall { + self.client() + .request_noparams("eth_chainId") + .map_resp(crate::utils::convert_u64 as fn(U64) -> u64) + .into() } /// Create an [EIP-2930] access list. @@ -170,7 +167,7 @@ pub trait Provider: &self, request: &'a N::TransactionRequest, ) -> RpcWithBlock { - RpcWithBlock::new(self.weak_client(), "eth_createAccessList", request) + self.client().request("eth_createAccessList", request).into() } /// This function returns an [`EthCall`] which can be used to get a gas estimate, @@ -186,7 +183,7 @@ pub trait Provider: fn estimate_gas<'req>( &self, tx: &'req N::TransactionRequest, - ) -> EthCall<'req, 'static, T, N, U128, u128> { + ) -> EthCall<'req, T, N, U128, u128> { EthCall::gas_estimate(self.weak_client(), tx).map_resp(crate::utils::convert_u128) } @@ -242,21 +239,24 @@ pub trait Provider: } /// Gets the current gas price in wei. - fn get_gas_price(&self) -> RpcCall { - self.client().request_noparams("eth_gasPrice").map_resp(crate::utils::convert_u128) + fn get_gas_price(&self) -> ProviderCall { + self.client() + .request_noparams("eth_gasPrice") + .map_resp(crate::utils::convert_u128 as fn(U128) -> u128) + .into() } /// Retrieves account information ([Account](alloy_consensus::Account)) for the given [Address] /// at the particular [BlockId]. fn get_account(&self, address: Address) -> RpcWithBlock { - RpcWithBlock::new(self.weak_client(), "eth_getAccount", address) + self.client().request("eth_getAccount", address).into() } /// Gets the balance of the account. /// /// Defaults to the latest block. See also [`RpcWithBlock::block_id`]. - fn get_balance(&self, address: Address) -> RpcWithBlock { - RpcWithBlock::new(self.weak_client(), "eth_getBalance", address) + fn get_balance(&self, address: Address) -> RpcWithBlock { + self.client().request("eth_getBalance", address).into() } /// Gets a block by either its hash, tag, or number, with full transactions or only hashes. @@ -324,16 +324,16 @@ pub trait Provider: } /// Gets the selected block [BlockId] receipts. - async fn get_block_receipts( + fn get_block_receipts( &self, block: BlockId, - ) -> TransportResult>> { - self.client().request("eth_getBlockReceipts", (block,)).await + ) -> ProviderCall>> { + self.client().request("eth_getBlockReceipts", (block,)).into() } /// Gets the bytecode located at the corresponding [Address]. fn get_code_at(&self, address: Address) -> RpcWithBlock { - RpcWithBlock::new(self.weak_client(), "eth_getCode", address) + self.client().request("eth_getCode", address).into() } /// Watch for new blocks by polling the provider with @@ -501,7 +501,7 @@ pub trait Provider: address: Address, keys: Vec, ) -> RpcWithBlock), EIP1186AccountProofResponse> { - RpcWithBlock::new(self.weak_client(), "eth_getProof", (address, keys)) + self.client().request("eth_getProof", (address, keys)).into() } /// Gets the specified storage value from [Address]. @@ -510,15 +510,15 @@ pub trait Provider: address: Address, key: U256, ) -> RpcWithBlock { - RpcWithBlock::new(self.weak_client(), "eth_getStorageAt", (address, key)) + self.client().request("eth_getStorageAt", (address, key)).into() } /// Gets a transaction by its [TxHash]. - async fn get_transaction_by_hash( + fn get_transaction_by_hash( &self, hash: TxHash, - ) -> TransportResult> { - self.client().request("eth_getTransactionByHash", (hash,)).await + ) -> ProviderCall> { + self.client().request("eth_getTransactionByHash", (hash,)).into() } /// Returns the EIP-2718 encoded transaction if it exists, see also @@ -529,24 +529,32 @@ pub trait Provider: /// [TxEip4844](alloy_consensus::transaction::eip4844::TxEip4844). /// /// This can be decoded into [TxEnvelope](alloy_consensus::transaction::TxEnvelope). - async fn get_raw_transaction_by_hash(&self, hash: TxHash) -> TransportResult> { - self.client().request("eth_getRawTransactionByHash", (hash,)).await + fn get_raw_transaction_by_hash( + &self, + hash: TxHash, + ) -> ProviderCall> { + self.client().request("eth_getRawTransactionByHash", (hash,)).into() } /// Gets the transaction count (AKA "nonce") of the corresponding address. #[doc(alias = "get_nonce")] #[doc(alias = "get_account_nonce")] - fn get_transaction_count(&self, address: Address) -> RpcWithBlock { - RpcWithBlock::new(self.weak_client(), "eth_getTransactionCount", address) - .map_resp(crate::utils::convert_u64) + fn get_transaction_count( + &self, + address: Address, + ) -> RpcWithBlock u64> { + self.client() + .request("eth_getTransactionCount", address) + .map_resp(crate::utils::convert_u64 as fn(U64) -> u64) + .into() } /// Gets a transaction receipt if it exists, by its [TxHash]. - async fn get_transaction_receipt( + fn get_transaction_receipt( &self, hash: TxHash, - ) -> TransportResult> { - self.client().request("eth_getTransactionReceipt", (hash,)).await + ) -> ProviderCall> { + self.client().request("eth_getTransactionReceipt", (hash,)).into() } /// Gets an uncle block through the tag [BlockId] and index [u64]. @@ -581,11 +589,11 @@ pub trait Provider: } /// Returns a suggestion for the current `maxPriorityFeePerGas` in wei. - async fn get_max_priority_fee_per_gas(&self) -> TransportResult { + fn get_max_priority_fee_per_gas(&self) -> ProviderCall { self.client() .request_noparams("eth_maxPriorityFeePerGas") - .await - .map(|fee: U128| fee.to::()) + .map_resp(utils::convert_u128 as fn(U128) -> u128) + .into() } /// Notify the provider that we are interested in new blocks. @@ -869,25 +877,28 @@ pub trait Provider: } /// Gets syncing info. - async fn syncing(&self) -> TransportResult { - self.client().request_noparams("eth_syncing").await + fn syncing(&self) -> ProviderCall { + self.client().request_noparams("eth_syncing").into() } /// Gets the client version. #[doc(alias = "web3_client_version")] - async fn get_client_version(&self) -> TransportResult { - self.client().request_noparams("web3_clientVersion").await + fn get_client_version(&self) -> ProviderCall { + self.client().request_noparams("web3_clientVersion").into() } /// Gets the `Keccak-256` hash of the given data. #[doc(alias = "web3_sha3")] - async fn get_sha3(&self, data: &[u8]) -> TransportResult { - self.client().request("web3_sha3", (hex::encode_prefixed(data),)).await + fn get_sha3(&self, data: &[u8]) -> ProviderCall { + self.client().request("web3_sha3", (hex::encode_prefixed(data),)).into() } /// Gets the network ID. Same as `eth_chainId`. - fn get_net_version(&self) -> RpcCall { - self.client().request_noparams("net_version").map_resp(crate::utils::convert_u64) + fn get_net_version(&self) -> ProviderCall { + self.client() + .request_noparams("net_version") + .map_resp(crate::utils::convert_u64 as fn(U64) -> u64) + .into() } /* ---------------------------------------- raw calls --------------------------------------- */ @@ -1383,14 +1394,35 @@ mod tests { assert_eq!(0, num.to::()) } + #[cfg(feature = "anvil-api")] #[tokio::test] async fn gets_transaction_count() { init_tracing(); let provider = ProviderBuilder::new().on_anvil(); - let count = provider - .get_transaction_count(address!("328375e18E7db8F1CA9d9bA8bF3E9C94ee34136A")) - .await - .unwrap(); + let accounts = provider.get_accounts().await.unwrap(); + let sender = accounts[0]; + + // Initial tx count should be 0 + let count = provider.get_transaction_count(sender).await.unwrap(); + assert_eq!(count, 0); + + // Send Tx + let tx = TransactionRequest { + value: Some(U256::from(100)), + from: Some(sender), + to: Some(address!("d8dA6BF26964aF9D7eEd9e03E53415D37aA96045").into()), + gas_price: Some(20e9 as u128), + gas: Some(21000), + ..Default::default() + }; + let _ = provider.send_transaction(tx).await.unwrap().get_receipt().await; + + // Tx count should be 1 + let count = provider.get_transaction_count(sender).await.unwrap(); + assert_eq!(count, 1); + + // Tx count should be 0 at block 0 + let count = provider.get_transaction_count(sender).block_id(0.into()).await.unwrap(); assert_eq!(count, 0); } @@ -1652,6 +1684,9 @@ mod tests { .with_input(bytes!("06fdde03")); // `name()` let result = provider.call(&req).await.unwrap(); assert_eq!(String::abi_decode(&result, true).unwrap(), "Wrapped Ether"); + + let result = provider.call(&req).block(0.into()).await.unwrap(); + assert_eq!(result.to_string(), "0x"); } #[tokio::test] diff --git a/crates/provider/src/provider/with_block.rs b/crates/provider/src/provider/with_block.rs index 471e310c156..d3fcd300957 100644 --- a/crates/provider/src/provider/with_block.rs +++ b/crates/provider/src/provider/with_block.rs @@ -1,37 +1,60 @@ use alloy_eips::BlockId; -use alloy_json_rpc::{RpcError, RpcParam, RpcReturn}; +use alloy_json_rpc::{RpcParam, RpcReturn}; use alloy_primitives::B256; -use alloy_rpc_client::{RpcCall, WeakClient}; -use alloy_transport::{Transport, TransportErrorKind, TransportResult}; -use futures::FutureExt; -use std::{ - borrow::Cow, - future::{Future, IntoFuture}, - marker::PhantomData, - task::Poll, -}; +use alloy_rpc_client::RpcCall; +use alloy_transport::{Transport, TransportResult}; +use std::future::IntoFuture; -/// States of the [`RpcWithBlock`] future. -#[derive(Clone)] -enum States Output> +use crate::ProviderCall; + +/// Helper struct that houses the params along with the BlockId. +#[derive(Debug, Clone)] +pub struct ParamsWithBlock { + params: Params, + block_id: BlockId, +} + +impl serde::Serialize for ParamsWithBlock { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + // Serialize params to a Value first + let mut ser = serde_json::to_value(&self.params).map_err(serde::ser::Error::custom)?; + + // serialize the block id + let block_id = serde_json::to_value(self.block_id).map_err(serde::ser::Error::custom)?; + + if let serde_json::Value::Array(ref mut arr) = ser { + arr.push(block_id); + } else if ser.is_null() { + ser = serde_json::Value::Array(vec![block_id]); + } else { + ser = serde_json::Value::Array(vec![ser, block_id]); + } + + ser.serialize(serializer) + } +} + +type ProviderCallProducer = + Box ProviderCall, Resp, Output, Map> + Send>; + +/// Container for varous types of calls dependent on a block id. +enum WithBlockInner Output> where T: Transport + Clone, Params: RpcParam, Resp: RpcReturn, Map: Fn(Resp) -> Output, { - Invalid, - Preparing { - client: WeakClient, - method: Cow<'static, str>, - params: Params, - block_id: BlockId, - map: Map, - }, - Running(RpcCall), + /// [RpcCall] which params are getting wrapped into [ParamsWithBlock] once the block id is set. + RpcCall(RpcCall), + /// Closure that produces a [ProviderCall] once the block id is set. + ProviderCall(ProviderCallProducer), } -impl core::fmt::Debug for States +impl core::fmt::Debug for WithBlockInner where T: Transport + Clone, Params: RpcParam, @@ -40,163 +63,77 @@ where { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - Self::Invalid => f.debug_tuple("Invalid").finish(), - Self::Preparing { client, method, params, block_id, .. } => f - .debug_struct("Preparing") - .field("client", client) - .field("method", method) - .field("params", params) - .field("block_id", block_id) - .finish(), - Self::Running(arg0) => f.debug_tuple("Running").field(arg0).finish(), + Self::RpcCall(call) => f.debug_tuple("RpcCall").field(call).finish(), + Self::ProviderCall(_) => f.debug_struct("ProviderCall").finish(), } } } -/// A future for [`RpcWithBlock`]. Simple wrapper around [`RpcCall`]. -#[derive(Debug, Clone)] +/// A struct that takes an optional [`BlockId`] parameter. +/// +/// This resolves to a [`ProviderCall`] that will execute the call on the specified block. +/// +/// By default this will use "latest". #[pin_project::pin_project] -#[allow(unnameable_types)] -pub struct RpcWithBlockFut +#[derive(Debug)] +pub struct RpcWithBlock Output> where T: Transport + Clone, Params: RpcParam, Resp: RpcReturn, - Map: Fn(Resp) -> Output, + Map: Fn(Resp) -> Output + Clone, { - state: States, + inner: WithBlockInner, + block_id: BlockId, } -impl RpcWithBlockFut +impl RpcWithBlock where T: Transport + Clone, Params: RpcParam, Resp: RpcReturn, - Output: 'static, - Map: Fn(Resp) -> Output, + Map: Fn(Resp) -> Output + Clone, { - fn poll_preparing( - self: std::pin::Pin<&mut Self>, - cx: &mut std::task::Context<'_>, - ) -> Poll> { - let this = self.project(); - let States::Preparing { client, method, params, block_id, map } = - std::mem::replace(this.state, States::Invalid) - else { - unreachable!("bad state") - }; - - let mut fut = { - // make sure the client still exists - let client = match client.upgrade().ok_or_else(TransportErrorKind::backend_gone) { - Ok(client) => client, - Err(e) => return Poll::Ready(Err(e)), - }; - - // serialize the params - let ser = serde_json::to_value(params).map_err(RpcError::ser_err); - let mut ser = match ser { - Ok(ser) => ser, - Err(e) => return Poll::Ready(Err(e)), - }; - - // serialize the block id - let block_id = serde_json::to_value(block_id).map_err(RpcError::ser_err); - let block_id = match block_id { - Ok(block_id) => block_id, - Err(e) => return Poll::Ready(Err(e)), - }; - - // append the block id to the params - if let serde_json::Value::Array(ref mut arr) = ser { - arr.push(block_id); - } else if ser.is_null() { - ser = serde_json::Value::Array(vec![block_id]); - } else { - ser = serde_json::Value::Array(vec![ser, block_id]); - } - - // create the call - client.request(method.clone(), ser).map_resp(map) - }; - // poll the call immediately - match fut.poll_unpin(cx) { - Poll::Ready(value) => Poll::Ready(value), - Poll::Pending => { - *this.state = States::Running(fut); - Poll::Pending - } - } + /// Create a new [`RpcWithBlock`] from a [`RpcCall`]. + pub fn new_rpc(inner: RpcCall) -> Self { + Self { inner: WithBlockInner::RpcCall(inner), block_id: Default::default() } } - fn poll_running( - self: std::pin::Pin<&mut Self>, - cx: &mut std::task::Context<'_>, - ) -> Poll> { - let States::Running(call) = self.project().state else { unreachable!("bad state") }; - call.poll_unpin(cx) + /// Create a new [`RpcWithBlock`] from a closure producing a [`ProviderCall`]. + pub fn new_provider(get_call: F) -> Self + where + F: Fn(BlockId) -> ProviderCall, Resp, Output, Map> + + Send + + 'static, + { + let get_call = Box::new(get_call); + Self { inner: WithBlockInner::ProviderCall(get_call), block_id: Default::default() } } } -impl Future for RpcWithBlockFut +impl From> + for RpcWithBlock where T: Transport + Clone, Params: RpcParam, Resp: RpcReturn, - Output: 'static, - Map: Fn(Resp) -> Output, + Map: Fn(Resp) -> Output + Clone, { - type Output = TransportResult; - - fn poll(self: std::pin::Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> Poll { - if matches!(self.state, States::Preparing { .. }) { - self.poll_preparing(cx) - } else if matches!(self.state, States::Running { .. }) { - self.poll_running(cx) - } else { - panic!("bad state") - } + fn from(inner: RpcCall) -> Self { + Self::new_rpc(inner) } } -/// An [`RpcCall`] that takes an optional [`BlockId`] parameter. By default -/// this will use "latest". -#[derive(Debug, Clone)] -pub struct RpcWithBlock Output> -where - T: Transport + Clone, - Params: RpcParam, - Resp: RpcReturn, - Map: Fn(Resp) -> Output, -{ - client: WeakClient, - method: Cow<'static, str>, - params: Params, - block_id: BlockId, - map: Map, - _pd: PhantomData (Resp, Output)>, -} - -impl RpcWithBlock +impl From for RpcWithBlock where T: Transport + Clone, Params: RpcParam, Resp: RpcReturn, + Map: Fn(Resp) -> Output + Clone, + F: Fn(BlockId) -> ProviderCall, Resp, Output, Map> + Send + 'static, { - /// Create a new [`RpcWithBlock`] instance. - pub fn new( - client: WeakClient, - method: impl Into>, - params: Params, - ) -> Self { - Self { - client, - method: method.into(), - params, - block_id: Default::default(), - map: std::convert::identity, - _pd: PhantomData, - } + fn from(inner: F) -> Self { + Self::new_provider(inner) } } @@ -205,26 +142,8 @@ where T: Transport + Clone, Params: RpcParam, Resp: RpcReturn, - Map: Fn(Resp) -> Output, + Map: Fn(Resp) -> Output + Clone, { - /// Map the response. - pub fn map_resp( - self, - map: NewMap, - ) -> RpcWithBlock - where - NewMap: Fn(Resp) -> NewOutput, - { - RpcWithBlock { - client: self.client, - method: self.method, - params: self.params, - block_id: self.block_id, - map, - _pd: PhantomData, - } - } - /// Set the block id. pub const fn block_id(mut self, block_id: BlockId) -> Self { self.block_id = block_id; @@ -280,21 +199,20 @@ where Params: RpcParam, Resp: RpcReturn, Output: 'static, - Map: Fn(Resp) -> Output, + Map: Fn(Resp) -> Output + Clone, { type Output = TransportResult; - type IntoFuture = RpcWithBlockFut; + type IntoFuture = ProviderCall, Resp, Output, Map>; fn into_future(self) -> Self::IntoFuture { - RpcWithBlockFut { - state: States::Preparing { - client: self.client, - method: self.method, - params: self.params, - block_id: self.block_id, - map: self.map, - }, + match self.inner { + WithBlockInner::RpcCall(rpc_call) => { + let block_id = self.block_id; + let rpc_call = rpc_call.map_params(|params| ParamsWithBlock { params, block_id }); + ProviderCall::RpcCall(rpc_call) + } + WithBlockInner::ProviderCall(get_call) => get_call(self.block_id), } } } diff --git a/crates/rpc-client/src/batch.rs b/crates/rpc-client/src/batch.rs index 7affdac2994..0993d22825f 100644 --- a/crates/rpc-client/src/batch.rs +++ b/crates/rpc-client/src/batch.rs @@ -4,7 +4,8 @@ use alloy_json_rpc::{ RpcReturn, SerializedRequest, }; use alloy_transport::{Transport, TransportError, TransportErrorKind, TransportResult}; -use futures::channel::oneshot; +use futures::FutureExt; +use pin_project::pin_project; use serde_json::value::RawValue; use std::{ borrow::Cow, @@ -12,8 +13,12 @@ use std::{ future::{Future, IntoFuture}, marker::PhantomData, pin::Pin, - task::{self, ready, Poll}, + task::{ + self, ready, + Poll::{self, Ready}, + }, }; +use tokio::sync::oneshot; pub(crate) type Channel = oneshot::Sender>>; pub(crate) type ChannelMap = HashMap; @@ -35,29 +40,58 @@ pub struct BatchRequest<'a, T> { /// Awaits a single response for a request that has been included in a batch. #[must_use = "A Waiter does nothing unless the corresponding BatchRequest is sent via `send_batch` and `.await`, AND the Waiter is awaited."] +#[pin_project] #[derive(Debug)] -pub struct Waiter { +pub struct Waiter Output> { + #[pin] rx: oneshot::Receiver>>, - _resp: PhantomData Resp>, + map: Option, + _resp: PhantomData (Output, Resp)>, +} + +impl Waiter { + /// Map the response to a different type. This is usable for converting + /// the response to a more usable type, e.g. changing `U64` to `u64`. + /// + /// ## Note + /// + /// Carefully review the rust documentation on [fn pointers] before passing + /// them to this function. Unless the pointer is specifically coerced to a + /// `fn(_) -> _`, the `NewMap` will be inferred as that function's unique + /// type. This can lead to confusing error messages. + /// + /// [fn pointers]: https://doc.rust-lang.org/std/primitive.fn.html#creating-function-pointers + pub fn map_resp(self, map: NewMap) -> Waiter + where + NewMap: FnOnce(Resp) -> NewOutput, + { + Waiter { rx: self.rx, map: Some(map), _resp: PhantomData } + } } impl From>>> for Waiter { fn from(rx: oneshot::Receiver>>) -> Self { - Self { rx, _resp: PhantomData } + Self { rx, map: Some(std::convert::identity), _resp: PhantomData } } } -impl std::future::Future for Waiter +impl std::future::Future for Waiter where Resp: RpcReturn, + Map: FnOnce(Resp) -> Output, { - type Output = TransportResult; + type Output = TransportResult; + + fn poll(self: std::pin::Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll { + let this = self.get_mut(); - fn poll(mut self: std::pin::Pin<&mut Self>, cx: &mut task::Context<'_>) -> Poll { - Pin::new(&mut self.rx).poll(cx).map(|resp| match resp { - Ok(resp) => try_deserialize_ok(resp), - Err(e) => Err(TransportErrorKind::custom(e)), - }) + match ready!(this.rx.poll_unpin(cx)) { + Ok(resp) => { + let resp: Result = try_deserialize_ok(resp); + Ready(resp.map(this.map.take().expect("polled after completion"))) + } + Err(e) => Poll::Ready(Err(TransportErrorKind::custom(e))), + } } } diff --git a/crates/rpc-client/src/call.rs b/crates/rpc-client/src/call.rs index a1efca47f50..8c9efc60fab 100644 --- a/crates/rpc-client/src/call.rs +++ b/crates/rpc-client/src/call.rs @@ -4,13 +4,14 @@ use alloy_json_rpc::{ }; use alloy_transport::{RpcFut, Transport, TransportError, TransportResult}; use core::panic; +use futures::FutureExt; use serde_json::value::RawValue; use std::{ fmt, future::Future, marker::PhantomData, pin::Pin, - task::{self, Poll::Ready}, + task::{self, ready, Poll::Ready}, }; use tower::Service; @@ -139,11 +140,11 @@ pub struct RpcCall Output> where Conn: Transport + Clone, Params: RpcParam, - Map: Fn(Resp) -> Output, + Map: FnOnce(Resp) -> Output, { #[pin] state: CallState, - map: Map, + map: Option, _pd: core::marker::PhantomData (Resp, Output)>, } @@ -151,7 +152,7 @@ impl core::fmt::Debug for RpcCall Output, + Map: FnOnce(Resp) -> Output, { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { f.debug_struct("RpcCall").field("state", &self.state).finish() @@ -167,7 +168,7 @@ where pub fn new(req: Request, connection: Conn) -> Self { Self { state: CallState::Prepared { request: Some(req), connection }, - map: std::convert::identity, + map: Some(std::convert::identity), _pd: PhantomData, } } @@ -177,17 +178,27 @@ impl RpcCall where Conn: Transport + Clone, Params: RpcParam, - Map: Fn(Resp) -> Output, + Map: FnOnce(Resp) -> Output, { - /// Set a function to map the response into a different type. + /// Map the response to a different type. This is usable for converting + /// the response to a more usable type, e.g. changing `U64` to `u64`. + /// + /// ## Note + /// + /// Carefully review the rust documentation on [fn pointers] before passing + /// them to this function. Unless the pointer is specifically coerced to a + /// `fn(_) -> _`, the `NewMap` will be inferred as that function's unique + /// type. This can lead to confusing error messages. + /// + /// [fn pointers]: https://doc.rust-lang.org/std/primitive.fn.html#creating-function-pointers pub fn map_resp( self, map: NewMap, ) -> RpcCall where - NewMap: Fn(Resp) -> NewOutput, + NewMap: FnOnce(Resp) -> NewOutput, { - RpcCall { state: self.state, map, _pd: PhantomData } + RpcCall { state: self.state, map: Some(map), _pd: PhantomData } } /// Returns `true` if the request is a subscription. @@ -249,20 +260,37 @@ where }; request.as_mut().expect("no request in prepared") } + + /// Map the params of the request into a new type. + pub fn map_params( + self, + map: impl Fn(Params) -> NewParams, + ) -> RpcCall { + let CallState::Prepared { request, connection } = self.state else { + panic!("Cannot get request after request has been sent"); + }; + let request = request.expect("no request in prepared").map_params(map); + RpcCall { + state: CallState::Prepared { request: Some(request), connection }, + map: self.map, + _pd: PhantomData, + } + } } impl RpcCall where Conn: Transport + Clone, - Params: RpcParam + Clone, - Map: Fn(Resp) -> Output, + Params: RpcParam + ToOwned, + Params::Owned: RpcParam, + Map: FnOnce(Resp) -> Output, { /// Convert this call into one with owned params, by cloning the params. /// /// # Panics /// - /// Panics if called after the request has been sent. - pub fn into_owned_params(self) -> RpcCall { + /// Panics if called after the request has been polled. + pub fn into_owned_params(self) -> RpcCall { let CallState::Prepared { request, connection } = self.state else { panic!("Cannot get params after request has been sent"); }; @@ -282,7 +310,7 @@ where Params: RpcParam + 'a, Resp: RpcReturn, Output: 'static, - Map: Fn(Resp) -> Output + Send + 'a, + Map: FnOnce(Resp) -> Output + Send + 'a, { /// Convert this future into a boxed, pinned future, erasing its type. pub fn boxed(self) -> RpcFut<'a, Output> { @@ -296,13 +324,16 @@ where Params: RpcParam, Resp: RpcReturn, Output: 'static, - Map: Fn(Resp) -> Output, + Map: FnOnce(Resp) -> Output, { type Output = TransportResult; fn poll(self: Pin<&mut Self>, cx: &mut task::Context<'_>) -> task::Poll { trace!(?self.state, "polling RpcCall"); - let this = self.project(); - this.state.poll(cx).map(try_deserialize_ok).map(|r| r.map(this.map)) + + let this = self.get_mut(); + let resp = try_deserialize_ok(ready!(this.state.poll_unpin(cx))); + + Ready(resp.map(this.map.take().expect("polled after completion"))) } } From 16814826121120a3e15e89b76ab0e4e49ea616b3 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 18 Sep 2024 15:15:04 +0200 Subject: [PATCH 184/186] feat: add block num hash helper (#1304) --- crates/rpc-types-engine/src/payload.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/crates/rpc-types-engine/src/payload.rs b/crates/rpc-types-engine/src/payload.rs index 93e37fb0291..86c030f9503 100644 --- a/crates/rpc-types-engine/src/payload.rs +++ b/crates/rpc-types-engine/src/payload.rs @@ -7,7 +7,7 @@ use alloc::{ use alloy_consensus::{Blob, Bytes48}; use alloy_eips::{ eip4844::BlobTransactionSidecar, eip4895::Withdrawal, eip6110::DepositRequest, - eip7002::WithdrawalRequest, eip7251::ConsolidationRequest, + eip7002::WithdrawalRequest, eip7251::ConsolidationRequest, BlockNumHash, }; use alloy_primitives::{Address, Bloom, Bytes, B256, B64, U256}; use core::iter::{FromIterator, IntoIterator}; @@ -192,6 +192,13 @@ pub struct ExecutionPayloadV1 { pub transactions: Vec, } +impl ExecutionPayloadV1 { + /// Returns the block number and hash as a [`BlockNumHash`]. + pub const fn block_num_hash(&self) -> BlockNumHash { + BlockNumHash::new(self.block_number, self.block_hash) + } +} + /// This structure maps on the ExecutionPayloadV2 structure of the beacon chain spec. /// /// See also: @@ -843,6 +850,11 @@ impl ExecutionPayload { self.as_v1().block_number } + /// Returns the block number for this payload. + pub const fn block_num_hash(&self) -> BlockNumHash { + self.as_v1().block_num_hash() + } + /// Returns the prev randao for this payload. pub const fn prev_randao(&self) -> B256 { self.as_v1().prev_randao From 237693b75712fe9c8734e96e72867f4281238747 Mon Sep 17 00:00:00 2001 From: Matthias Seitz Date: Wed, 18 Sep 2024 15:29:30 +0200 Subject: [PATCH 185/186] chore: release 0.3.6 --- CHANGELOG.md | 27 ++++++++++++++++++++++++++ Cargo.toml | 2 +- crates/alloy/CHANGELOG.md | 7 +++++++ crates/consensus/CHANGELOG.md | 6 ++++++ crates/contract/CHANGELOG.md | 16 +++++++++++++++ crates/eip7547/CHANGELOG.md | 1 + crates/eips/CHANGELOG.md | 13 +++++++++++++ crates/genesis/CHANGELOG.md | 6 ++++++ crates/json-rpc/CHANGELOG.md | 12 ++++++++++++ crates/network-primitives/CHANGELOG.md | 6 ++++++ crates/network/CHANGELOG.md | 12 ++++++++++++ crates/node-bindings/CHANGELOG.md | 12 ++++++++++++ crates/provider/CHANGELOG.md | 17 ++++++++++++++++ crates/pubsub/CHANGELOG.md | 6 ++++++ crates/rpc-client/CHANGELOG.md | 13 +++++++++++++ crates/rpc-types-admin/CHANGELOG.md | 6 ++++++ crates/rpc-types-anvil/CHANGELOG.md | 6 ++++++ crates/rpc-types-beacon/CHANGELOG.md | 12 ++++++++++++ crates/rpc-types-debug/CHANGELOG.md | 12 ++++++++++++ crates/rpc-types-engine/CHANGELOG.md | 11 +++++++++++ crates/rpc-types-eth/CHANGELOG.md | 13 +++++++++++++ crates/rpc-types-mev/CHANGELOG.md | 6 ++++++ crates/rpc-types-trace/CHANGELOG.md | 12 ++++++++++++ crates/rpc-types-txpool/CHANGELOG.md | 6 ++++++ crates/rpc-types/CHANGELOG.md | 6 ++++++ crates/serde/CHANGELOG.md | 6 ++++++ crates/signer-aws/CHANGELOG.md | 6 ++++++ crates/signer-gcp/CHANGELOG.md | 6 ++++++ crates/signer-ledger/CHANGELOG.md | 6 ++++++ crates/signer-local/CHANGELOG.md | 6 ++++++ crates/signer-trezor/CHANGELOG.md | 6 ++++++ crates/signer/CHANGELOG.md | 6 ++++++ crates/transport-http/CHANGELOG.md | 12 ++++++++++++ crates/transport-ipc/CHANGELOG.md | 6 ++++++ crates/transport-ws/CHANGELOG.md | 6 ++++++ crates/transport/CHANGELOG.md | 6 ++++++ 36 files changed, 317 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc1ebcf40b0..03c481e6348 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,32 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Bug Fixes + +- [types-eth] Optional Alloy Serde ([#1284](https://github.com/alloy-rs/alloy/issues/1284)) +- `eth_simulateV1` ([#1289](https://github.com/alloy-rs/alloy/issues/1289)) + +### Features + +- Add block num hash helper ([#1304](https://github.com/alloy-rs/alloy/issues/1304)) +- ProviderCall ([#788](https://github.com/alloy-rs/alloy/issues/788)) +- [rpc-types-beacon] `SignedBidSubmissionV4` ([#1303](https://github.com/alloy-rs/alloy/issues/1303)) +- [transport-http] Layer client ([#1227](https://github.com/alloy-rs/alloy/issues/1227)) +- Add blob and proof v1 ([#1300](https://github.com/alloy-rs/alloy/issues/1300)) +- Add types for flat call tracer ([#1292](https://github.com/alloy-rs/alloy/issues/1292)) +- [`node-bindings`] Support appending extra args ([#1299](https://github.com/alloy-rs/alloy/issues/1299)) + +### Miscellaneous Tasks + +- [rpc] Rename witness fields ([#1293](https://github.com/alloy-rs/alloy/issues/1293)) +- [engine] `no_std` Checks ([#1298](https://github.com/alloy-rs/alloy/issues/1298)) + +### Refactor + +- Separate transaction builders for tx types ([#1259](https://github.com/alloy-rs/alloy/issues/1259)) + ## [0.3.5](https://github.com/alloy-rs/alloy/releases/tag/v0.3.5) - 2024-09-13 ### Bug Fixes @@ -13,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.5 - Release 0.3.5 ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 diff --git a/Cargo.toml b/Cargo.toml index 416cce9e400..b75fe19a851 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,7 +3,7 @@ members = ["crates/*"] resolver = "2" [workspace.package] -version = "0.3.5" +version = "0.3.6" edition = "2021" rust-version = "1.79" authors = ["Alloy Contributors"] diff --git a/crates/alloy/CHANGELOG.md b/crates/alloy/CHANGELOG.md index 90a83338b4e..b1433b28383 100644 --- a/crates/alloy/CHANGELOG.md +++ b/crates/alloy/CHANGELOG.md @@ -5,10 +5,17 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Features + +- [transport-http] Layer client ([#1227](https://github.com/alloy-rs/alloy/issues/1227)) + ## [0.3.5](https://github.com/alloy-rs/alloy/releases/tag/v0.3.5) - 2024-09-13 ### Miscellaneous Tasks +- Release 0.3.5 - Release 0.3.5 ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 diff --git a/crates/consensus/CHANGELOG.md b/crates/consensus/CHANGELOG.md index 2d5e73b6bf8..634cf5acf9e 100644 --- a/crates/consensus/CHANGELOG.md +++ b/crates/consensus/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Miscellaneous Tasks diff --git a/crates/contract/CHANGELOG.md b/crates/contract/CHANGELOG.md index 523d84d6a30..6f4675e7a76 100644 --- a/crates/contract/CHANGELOG.md +++ b/crates/contract/CHANGELOG.md @@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Features + +- ProviderCall ([#788](https://github.com/alloy-rs/alloy/issues/788)) + +### Refactor + +- Separate transaction builders for tx types ([#1259](https://github.com/alloy-rs/alloy/issues/1259)) + +## [0.3.5](https://github.com/alloy-rs/alloy/releases/tag/v0.3.5) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Features diff --git a/crates/eip7547/CHANGELOG.md b/crates/eip7547/CHANGELOG.md index 6e08a67ddc6..9d8f8297bf6 100644 --- a/crates/eip7547/CHANGELOG.md +++ b/crates/eip7547/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Miscellaneous Tasks +- Release 0.3.5 - Release 0.3.5 ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 diff --git a/crates/eips/CHANGELOG.md b/crates/eips/CHANGELOG.md index 96461adab81..7b61b20667a 100644 --- a/crates/eips/CHANGELOG.md +++ b/crates/eips/CHANGELOG.md @@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Features + +- [rpc-types-beacon] `SignedBidSubmissionV4` ([#1303](https://github.com/alloy-rs/alloy/issues/1303)) +- Add blob and proof v1 ([#1300](https://github.com/alloy-rs/alloy/issues/1300)) + +## [0.3.5](https://github.com/alloy-rs/alloy/releases/tag/v0.3.5) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Features diff --git a/crates/genesis/CHANGELOG.md b/crates/genesis/CHANGELOG.md index d7bbdbfac44..d070777f633 100644 --- a/crates/genesis/CHANGELOG.md +++ b/crates/genesis/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Miscellaneous Tasks diff --git a/crates/json-rpc/CHANGELOG.md b/crates/json-rpc/CHANGELOG.md index 263d113a689..fb16a616108 100644 --- a/crates/json-rpc/CHANGELOG.md +++ b/crates/json-rpc/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Features + +- ProviderCall ([#788](https://github.com/alloy-rs/alloy/issues/788)) + +## [0.3.5](https://github.com/alloy-rs/alloy/releases/tag/v0.3.5) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Miscellaneous Tasks diff --git a/crates/network-primitives/CHANGELOG.md b/crates/network-primitives/CHANGELOG.md index 286bdd412b0..5fbdc6869f4 100644 --- a/crates/network-primitives/CHANGELOG.md +++ b/crates/network-primitives/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Miscellaneous Tasks diff --git a/crates/network/CHANGELOG.md b/crates/network/CHANGELOG.md index 22b42794f8d..d444553b9ac 100644 --- a/crates/network/CHANGELOG.md +++ b/crates/network/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Refactor + +- Separate transaction builders for tx types ([#1259](https://github.com/alloy-rs/alloy/issues/1259)) + +## [0.3.5](https://github.com/alloy-rs/alloy/releases/tag/v0.3.5) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Features diff --git a/crates/node-bindings/CHANGELOG.md b/crates/node-bindings/CHANGELOG.md index ebddc954e38..80a3196d0d3 100644 --- a/crates/node-bindings/CHANGELOG.md +++ b/crates/node-bindings/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Features + +- [`node-bindings`] Support appending extra args ([#1299](https://github.com/alloy-rs/alloy/issues/1299)) + +## [0.3.5](https://github.com/alloy-rs/alloy/releases/tag/v0.3.5) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Bug Fixes diff --git a/crates/provider/CHANGELOG.md b/crates/provider/CHANGELOG.md index 287875911a5..4c7e3625698 100644 --- a/crates/provider/CHANGELOG.md +++ b/crates/provider/CHANGELOG.md @@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Features + +- ProviderCall ([#788](https://github.com/alloy-rs/alloy/issues/788)) +- [transport-http] Layer client ([#1227](https://github.com/alloy-rs/alloy/issues/1227)) + +### Refactor + +- Separate transaction builders for tx types ([#1259](https://github.com/alloy-rs/alloy/issues/1259)) + +## [0.3.5](https://github.com/alloy-rs/alloy/releases/tag/v0.3.5) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Bug Fixes diff --git a/crates/pubsub/CHANGELOG.md b/crates/pubsub/CHANGELOG.md index 216c6c6f050..341f598414d 100644 --- a/crates/pubsub/CHANGELOG.md +++ b/crates/pubsub/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Miscellaneous Tasks diff --git a/crates/rpc-client/CHANGELOG.md b/crates/rpc-client/CHANGELOG.md index aa47395b369..306e53afd46 100644 --- a/crates/rpc-client/CHANGELOG.md +++ b/crates/rpc-client/CHANGELOG.md @@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Features + +- ProviderCall ([#788](https://github.com/alloy-rs/alloy/issues/788)) +- [transport-http] Layer client ([#1227](https://github.com/alloy-rs/alloy/issues/1227)) + +## [0.3.5](https://github.com/alloy-rs/alloy/releases/tag/v0.3.5) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Features diff --git a/crates/rpc-types-admin/CHANGELOG.md b/crates/rpc-types-admin/CHANGELOG.md index 3076665f832..a34d80468f8 100644 --- a/crates/rpc-types-admin/CHANGELOG.md +++ b/crates/rpc-types-admin/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Miscellaneous Tasks diff --git a/crates/rpc-types-anvil/CHANGELOG.md b/crates/rpc-types-anvil/CHANGELOG.md index 2df6e5bee3d..e2de5158595 100644 --- a/crates/rpc-types-anvil/CHANGELOG.md +++ b/crates/rpc-types-anvil/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Miscellaneous Tasks diff --git a/crates/rpc-types-beacon/CHANGELOG.md b/crates/rpc-types-beacon/CHANGELOG.md index 86dedc29830..a405f07bf04 100644 --- a/crates/rpc-types-beacon/CHANGELOG.md +++ b/crates/rpc-types-beacon/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Features + +- [rpc-types-beacon] `SignedBidSubmissionV4` ([#1303](https://github.com/alloy-rs/alloy/issues/1303)) + +## [0.3.5](https://github.com/alloy-rs/alloy/releases/tag/v0.3.5) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Features diff --git a/crates/rpc-types-debug/CHANGELOG.md b/crates/rpc-types-debug/CHANGELOG.md index fcc5e267023..c98c9d154af 100644 --- a/crates/rpc-types-debug/CHANGELOG.md +++ b/crates/rpc-types-debug/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Miscellaneous Tasks + +- [rpc] Rename witness fields ([#1293](https://github.com/alloy-rs/alloy/issues/1293)) + +## [0.3.5](https://github.com/alloy-rs/alloy/releases/tag/v0.3.5) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Miscellaneous Tasks diff --git a/crates/rpc-types-engine/CHANGELOG.md b/crates/rpc-types-engine/CHANGELOG.md index ea5b9aece2e..d948ed5b068 100644 --- a/crates/rpc-types-engine/CHANGELOG.md +++ b/crates/rpc-types-engine/CHANGELOG.md @@ -5,12 +5,23 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Features + +- Add block num hash helper ([#1304](https://github.com/alloy-rs/alloy/issues/1304)) +- [rpc-types-beacon] `SignedBidSubmissionV4` ([#1303](https://github.com/alloy-rs/alloy/issues/1303)) + ## [0.3.5](https://github.com/alloy-rs/alloy/releases/tag/v0.3.5) - 2024-09-13 ### Bug Fixes - Add missing conversion ([#1287](https://github.com/alloy-rs/alloy/issues/1287)) +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Features diff --git a/crates/rpc-types-eth/CHANGELOG.md b/crates/rpc-types-eth/CHANGELOG.md index 18ef35d55ba..6c9f56103b4 100644 --- a/crates/rpc-types-eth/CHANGELOG.md +++ b/crates/rpc-types-eth/CHANGELOG.md @@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Bug Fixes + +- [types-eth] Optional Alloy Serde ([#1284](https://github.com/alloy-rs/alloy/issues/1284)) +- `eth_simulateV1` ([#1289](https://github.com/alloy-rs/alloy/issues/1289)) + +## [0.3.5](https://github.com/alloy-rs/alloy/releases/tag/v0.3.5) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Bug Fixes diff --git a/crates/rpc-types-mev/CHANGELOG.md b/crates/rpc-types-mev/CHANGELOG.md index a55d730f02c..e10a2a16b5e 100644 --- a/crates/rpc-types-mev/CHANGELOG.md +++ b/crates/rpc-types-mev/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Miscellaneous Tasks diff --git a/crates/rpc-types-trace/CHANGELOG.md b/crates/rpc-types-trace/CHANGELOG.md index b56ddeea590..ee223341b04 100644 --- a/crates/rpc-types-trace/CHANGELOG.md +++ b/crates/rpc-types-trace/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Features + +- Add types for flat call tracer ([#1292](https://github.com/alloy-rs/alloy/issues/1292)) + +## [0.3.5](https://github.com/alloy-rs/alloy/releases/tag/v0.3.5) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Features diff --git a/crates/rpc-types-txpool/CHANGELOG.md b/crates/rpc-types-txpool/CHANGELOG.md index fca344e0a8e..421b6969c28 100644 --- a/crates/rpc-types-txpool/CHANGELOG.md +++ b/crates/rpc-types-txpool/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Miscellaneous Tasks diff --git a/crates/rpc-types/CHANGELOG.md b/crates/rpc-types/CHANGELOG.md index 19af1f7f415..93ef094113e 100644 --- a/crates/rpc-types/CHANGELOG.md +++ b/crates/rpc-types/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Features diff --git a/crates/serde/CHANGELOG.md b/crates/serde/CHANGELOG.md index c3367e2c79a..8b9c09517ec 100644 --- a/crates/serde/CHANGELOG.md +++ b/crates/serde/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Miscellaneous Tasks diff --git a/crates/signer-aws/CHANGELOG.md b/crates/signer-aws/CHANGELOG.md index 8dd96fd3ab9..f87c8ddcd24 100644 --- a/crates/signer-aws/CHANGELOG.md +++ b/crates/signer-aws/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Miscellaneous Tasks diff --git a/crates/signer-gcp/CHANGELOG.md b/crates/signer-gcp/CHANGELOG.md index add89ebf3e4..bd9432708af 100644 --- a/crates/signer-gcp/CHANGELOG.md +++ b/crates/signer-gcp/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Miscellaneous Tasks diff --git a/crates/signer-ledger/CHANGELOG.md b/crates/signer-ledger/CHANGELOG.md index 02b698dab13..11e5caa69db 100644 --- a/crates/signer-ledger/CHANGELOG.md +++ b/crates/signer-ledger/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Miscellaneous Tasks diff --git a/crates/signer-local/CHANGELOG.md b/crates/signer-local/CHANGELOG.md index 044fa381973..b1917212dfd 100644 --- a/crates/signer-local/CHANGELOG.md +++ b/crates/signer-local/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Miscellaneous Tasks diff --git a/crates/signer-trezor/CHANGELOG.md b/crates/signer-trezor/CHANGELOG.md index e3509906c92..7afff243630 100644 --- a/crates/signer-trezor/CHANGELOG.md +++ b/crates/signer-trezor/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Features diff --git a/crates/signer/CHANGELOG.md b/crates/signer/CHANGELOG.md index fb351d68f2f..7fc6ddf961e 100644 --- a/crates/signer/CHANGELOG.md +++ b/crates/signer/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Miscellaneous Tasks diff --git a/crates/transport-http/CHANGELOG.md b/crates/transport-http/CHANGELOG.md index f8f7eaeb128..d95903293ca 100644 --- a/crates/transport-http/CHANGELOG.md +++ b/crates/transport-http/CHANGELOG.md @@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Features + +- [transport-http] Layer client ([#1227](https://github.com/alloy-rs/alloy/issues/1227)) + +## [0.3.5](https://github.com/alloy-rs/alloy/releases/tag/v0.3.5) - 2024-09-13 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Miscellaneous Tasks diff --git a/crates/transport-ipc/CHANGELOG.md b/crates/transport-ipc/CHANGELOG.md index f5c8afe2449..fc2bd3b2f45 100644 --- a/crates/transport-ipc/CHANGELOG.md +++ b/crates/transport-ipc/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Miscellaneous Tasks diff --git a/crates/transport-ws/CHANGELOG.md b/crates/transport-ws/CHANGELOG.md index 55b0f4b8847..b9251dbab5c 100644 --- a/crates/transport-ws/CHANGELOG.md +++ b/crates/transport-ws/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Miscellaneous Tasks diff --git a/crates/transport/CHANGELOG.md b/crates/transport/CHANGELOG.md index f6207061d43..f11200ece95 100644 --- a/crates/transport/CHANGELOG.md +++ b/crates/transport/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.3.6](https://github.com/alloy-rs/alloy/releases/tag/v0.3.6) - 2024-09-18 + +### Miscellaneous Tasks + +- Release 0.3.5 + ## [0.3.4](https://github.com/alloy-rs/alloy/releases/tag/v0.3.4) - 2024-09-13 ### Miscellaneous Tasks From 718aee579dc000019582245226eebf8b40d24c41 Mon Sep 17 00:00:00 2001 From: Roshan Date: Fri, 20 Sep 2024 11:04:57 +0800 Subject: [PATCH 186/186] chore: resolve merge conflicts --- crates/rpc-types-eth/src/sidecars.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/crates/rpc-types-eth/src/sidecars.rs b/crates/rpc-types-eth/src/sidecars.rs index 040cd7372b4..97902840301 100644 --- a/crates/rpc-types-eth/src/sidecars.rs +++ b/crates/rpc-types-eth/src/sidecars.rs @@ -2,30 +2,31 @@ use alloy_eips::eip4844::BlobTransactionSidecar; use alloy_primitives::B256; -use serde::{Deserialize, Serialize}; /// Block sidecar representation -#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] +#[derive(Clone, Debug, Default, PartialEq, Eq)] +#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] +#[cfg_attr(feature = "serde", serde(rename_all = "camelCase"))] pub struct BlockSidecar { /// Transaction sidecar. - #[serde(default)] + #[cfg_attr(feature = "serde", serde(default))] pub blob_sidecar: BlobTransactionSidecar, /// Block hash. - #[serde(default)] + #[cfg_attr(feature = "serde", serde(default))] pub block_hash: B256, /// Block number. - #[serde(default, with = "alloy_serde::quantity")] + #[cfg_attr(feature = "serde", serde(default, with = "alloy_serde::quantity"))] pub block_number: u64, /// Transaction hash. - #[serde(default)] + #[cfg_attr(feature = "serde", serde(default))] pub tx_hash: B256, /// Transaction index. - #[serde(default, with = "alloy_serde::quantity")] + #[cfg_attr(feature = "serde", serde(default, with = "alloy_serde::quantity"))] pub tx_index: u64, } #[test] +#[cfg(feature = "serde")] fn test_block_sidecar() { let block_sidecar = BlockSidecar { blob_sidecar: BlobTransactionSidecar::default(),