diff --git a/Cargo.lock b/Cargo.lock index 7af77d7f6a2..4544b9c0d96 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -172,9 +172,9 @@ dependencies = [ [[package]] name = "alloy-rlp" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f938f00332d63a5b0ac687bd6f46d03884638948921d9f8b50c59563d421ae25" +checksum = "cc0fac0fc16baf1f63f78b47c3d24718f3619b0714076f6a02957d808d52cbef" dependencies = [ "alloy-rlp-derive", "arrayvec", @@ -184,9 +184,9 @@ dependencies = [ [[package]] name = "alloy-rlp-derive" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aa5bb468bc7c46e0c5074d418f575262ff79451242e5ac1380121ed4e23c4fd" +checksum = "c0391754c09fab4eae3404d19d0d297aa1c670c1775ab51d8a5312afeca23157" dependencies = [ "proc-macro2", "quote", @@ -2077,12 +2077,12 @@ dependencies = [ name = "ef-tests" version = "0.1.0-alpha.8" dependencies = [ + "alloy-rlp", "reth-db", "reth-interfaces", "reth-primitives", "reth-provider", "reth-revm", - "reth-rlp", "reth-stages", "serde", "serde_json", @@ -2499,12 +2499,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "ethnum" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8ff382b2fa527fb7fb06eeebfc5bbb3f17e3cc6b9d70b006c41daa8824adac" - [[package]] name = "event-listener" version = "2.5.3" @@ -5293,6 +5287,7 @@ dependencies = [ name = "reth" version = "0.1.0-alpha.8" dependencies = [ + "alloy-rlp", "aquamarine", "backon", "boyer-moore-magiclen", @@ -5337,7 +5332,6 @@ dependencies = [ "reth-prune", "reth-revm", "reth-revm-inspectors", - "reth-rlp", "reth-rpc", "reth-rpc-api", "reth-rpc-builder", @@ -5382,6 +5376,7 @@ dependencies = [ name = "reth-basic-payload-builder" version = "0.1.0-alpha.8" dependencies = [ + "alloy-rlp", "futures-core", "futures-util", "metrics", @@ -5391,7 +5386,6 @@ dependencies = [ "reth-primitives", "reth-provider", "reth-revm", - "reth-rlp", "reth-tasks", "reth-transaction-pool", "revm", @@ -5539,6 +5533,7 @@ dependencies = [ name = "reth-discv4" version = "0.1.0-alpha.8" dependencies = [ + "alloy-rlp", "discv5", "enr", "generic-array", @@ -5547,8 +5542,6 @@ dependencies = [ "reth-net-common", "reth-net-nat", "reth-primitives", - "reth-rlp", - "reth-rlp-derive", "reth-tracing", "rlp", "secp256k1", @@ -5563,6 +5556,7 @@ dependencies = [ name = "reth-dns-discovery" version = "0.1.0-alpha.8" dependencies = [ + "alloy-rlp", "async-trait", "data-encoding", "enr", @@ -5570,7 +5564,6 @@ dependencies = [ "parking_lot 0.12.1", "reth-net-common", "reth-primitives", - "reth-rlp", "reth-tracing", "schnellru", "secp256k1", @@ -5587,6 +5580,7 @@ dependencies = [ name = "reth-downloaders" version = "0.1.0-alpha.8" dependencies = [ + "alloy-rlp", "assert_matches", "futures", "futures-util", @@ -5598,7 +5592,6 @@ dependencies = [ "reth-interfaces", "reth-metrics", "reth-primitives", - "reth-rlp", "reth-tasks", "reth-tracing", "tempfile", @@ -5614,6 +5607,7 @@ name = "reth-ecies" version = "0.1.0-alpha.8" dependencies = [ "aes 0.8.3", + "alloy-rlp", "block-padding", "byteorder", "cipher 0.4.4", @@ -5627,7 +5621,6 @@ dependencies = [ "rand 0.8.5", "reth-net-common", "reth-primitives", - "reth-rlp", "secp256k1", "sha2", "sha3", @@ -5643,6 +5636,7 @@ dependencies = [ name = "reth-eth-wire" version = "0.1.0-alpha.8" dependencies = [ + "alloy-rlp", "arbitrary", "async-trait", "bytes", @@ -5658,7 +5652,6 @@ dependencies = [ "reth-ecies", "reth-metrics", "reth-primitives", - "reth-rlp", "reth-tracing", "secp256k1", "serde", @@ -5799,6 +5792,7 @@ dependencies = [ name = "reth-network" version = "0.1.0-alpha.8" dependencies = [ + "alloy-rlp", "aquamarine", "async-trait", "auto_impl", @@ -5827,8 +5821,6 @@ dependencies = [ "reth-network-api", "reth-primitives", "reth-provider", - "reth-rlp", - "reth-rlp-derive", "reth-rpc-types", "reth-tasks", "reth-tracing", @@ -5882,13 +5874,13 @@ dependencies = [ name = "reth-payload-builder" version = "0.1.0-alpha.8" dependencies = [ + "alloy-rlp", "futures-util", "metrics", "reth-interfaces", "reth-metrics", "reth-primitives", "reth-revm-primitives", - "reth-rlp", "reth-rpc-types", "reth-rpc-types-compat", "reth-transaction-pool", @@ -5906,6 +5898,7 @@ name = "reth-primitives" version = "0.1.0-alpha.8" dependencies = [ "alloy-primitives", + "alloy-rlp", "arbitrary", "assert_matches", "byteorder", @@ -5926,8 +5919,6 @@ dependencies = [ "rand 0.8.5", "rayon", "reth-codecs", - "reth-rlp", - "reth-rlp-derive", "revm-primitives", "ruint", "secp256k1", @@ -5953,6 +5944,7 @@ dependencies = [ name = "reth-provider" version = "0.1.0-alpha.8" dependencies = [ + "alloy-rlp", "assert_matches", "auto_impl", "itertools 0.11.0", @@ -5963,7 +5955,6 @@ dependencies = [ "reth-interfaces", "reth-primitives", "reth-revm-primitives", - "reth-rlp", "reth-trie", "revm", "tempfile", @@ -6027,38 +6018,11 @@ dependencies = [ "reth-primitives", ] -[[package]] -name = "reth-rlp" -version = "0.1.0-alpha.8" -dependencies = [ - "arrayvec", - "auto_impl", - "bytes", - "c-kzg 0.1.0 (git+https://github.com/ethereum/c-kzg-4844?rev=fbef59a3f9e8fa998bdb5069d212daf83d586aa5)", - "criterion", - "ethereum-types", - "ethnum", - "hex-literal", - "pprof", - "reth-rlp", - "reth-rlp-derive", - "revm-primitives", - "smol_str", -] - -[[package]] -name = "reth-rlp-derive" -version = "0.1.0-alpha.8" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.37", -] - [[package]] name = "reth-rpc" version = "0.1.0-alpha.8" dependencies = [ + "alloy-rlp", "assert_matches", "async-trait", "bytes", @@ -6081,7 +6045,6 @@ dependencies = [ "reth-primitives", "reth-provider", "reth-revm", - "reth-rlp", "reth-rpc-api", "reth-rpc-engine-api", "reth-rpc-types", @@ -6165,6 +6128,7 @@ dependencies = [ name = "reth-rpc-engine-api" version = "0.1.0-alpha.8" dependencies = [ + "alloy-rlp", "assert_matches", "async-trait", "jsonrpsee-core", @@ -6174,7 +6138,6 @@ dependencies = [ "reth-payload-builder", "reth-primitives", "reth-provider", - "reth-rlp", "reth-rpc-api", "reth-rpc-types", "reth-rpc-types-compat", @@ -6188,11 +6151,11 @@ dependencies = [ name = "reth-rpc-types" version = "0.1.0-alpha.8" dependencies = [ + "alloy-rlp", "itertools 0.11.0", "jsonrpsee-types", "rand 0.8.5", "reth-primitives", - "reth-rlp", "serde", "serde_json", "similar-asserts", @@ -6203,8 +6166,8 @@ dependencies = [ name = "reth-rpc-types-compat" version = "0.1.0-alpha.8" dependencies = [ + "alloy-rlp", "reth-primitives", - "reth-rlp", "reth-rpc-types", ] @@ -6212,6 +6175,7 @@ dependencies = [ name = "reth-stages" version = "0.1.0-alpha.8" dependencies = [ + "alloy-rlp", "aquamarine", "assert_matches", "async-trait", @@ -6235,7 +6199,6 @@ dependencies = [ "reth-primitives", "reth-provider", "reth-revm", - "reth-rlp", "reth-trie", "revm", "serde", @@ -6275,6 +6238,7 @@ dependencies = [ name = "reth-transaction-pool" version = "0.1.0-alpha.8" dependencies = [ + "alloy-rlp", "aquamarine", "assert_matches", "async-trait", @@ -6292,7 +6256,6 @@ dependencies = [ "reth-metrics", "reth-primitives", "reth-provider", - "reth-rlp", "reth-tasks", "serde", "thiserror", @@ -6305,6 +6268,7 @@ dependencies = [ name = "reth-trie" version = "0.1.0-alpha.8" dependencies = [ + "alloy-rlp", "criterion", "derive_more", "pretty_assertions", @@ -6313,7 +6277,6 @@ dependencies = [ "reth-interfaces", "reth-primitives", "reth-provider", - "reth-rlp", "thiserror", "tokio", "tokio-stream", diff --git a/Cargo.toml b/Cargo.toml index 3767bec92cf..a18402e456b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,8 +25,6 @@ members = [ "crates/revm", "crates/revm/revm-primitives", "crates/revm/revm-inspectors", - "crates/rlp", - "crates/rlp/rlp-derive", "crates/rpc/ipc", "crates/rpc/rpc", "crates/rpc/rpc-api", @@ -84,7 +82,6 @@ reth-primitives = { path = "./crates/primitives" } reth-interfaces = { path = "./crates/interfaces" } reth-provider = { path = "./crates/storage/provider" } reth-db = { path = "./crates/storage/db" } -reth-rlp = { path = "./crates/rlp" } reth-rpc-types = { path = "./crates/rpc/rpc-types" } reth-rpc-builder = { path = "./crates/rpc/rpc-builder" } reth-blockchain-tree = { path = "./crates/blockchain-tree" } @@ -104,6 +101,7 @@ revm-primitives = { git = "https://github.com/Evalir/revm/", branch = "reintrodu ## eth alloy-primitives = "0.3" +alloy-rlp = "0.3" ethers-core = { version = "2.0", default-features = false } ethers-providers = { version = "2.0", default-features = false } ethers-signers = { version = "2.0", default-features = false } diff --git a/bin/reth/Cargo.toml b/bin/reth/Cargo.toml index a562895265d..8869b779eb1 100644 --- a/bin/reth/Cargo.toml +++ b/bin/reth/Cargo.toml @@ -37,7 +37,6 @@ reth-rpc-builder = { path = "../../crates/rpc/rpc-builder" } reth-rpc = { path = "../../crates/rpc/rpc" } reth-rpc-types = { path = "../../crates/rpc/rpc-types" } reth-rpc-api = { path = "../../crates/rpc/rpc-api" } -reth-rlp.workspace = true reth-network = { path = "../../crates/net/network", features = ["serde"] } reth-network-api.workspace = true reth-downloaders = { path = "../../crates/net/downloaders", features = ["test-utils"] } @@ -51,6 +50,7 @@ reth-prune = { path = "../../crates/prune" } reth-trie = { path = "../../crates/trie" } # crypto +alloy-rlp.workspace = true secp256k1 = { workspace = true, features = ["global-context", "rand-std", "recovery"] } # tracing diff --git a/bin/reth/src/cli/config.rs b/bin/reth/src/cli/config.rs index e34540a7a1a..5c10a001a37 100644 --- a/bin/reth/src/cli/config.rs +++ b/bin/reth/src/cli/config.rs @@ -1,7 +1,7 @@ //! Config traits for various node components. +use alloy_rlp::Encodable; use reth_primitives::{Bytes, BytesMut}; -use reth_rlp::Encodable; use reth_rpc::{eth::gas_oracle::GasPriceOracleConfig, JwtError, JwtSecret}; use reth_rpc_builder::{ auth::AuthServerConfig, error::RpcError, EthConfig, IpcServerBuilder, RpcServerConfig, diff --git a/crates/net/discv4/Cargo.toml b/crates/net/discv4/Cargo.toml index f81ccbde394..95fb6bc92d0 100644 --- a/crates/net/discv4/Cargo.toml +++ b/crates/net/discv4/Cargo.toml @@ -13,12 +13,11 @@ Ethereum network discovery [dependencies] # reth reth-primitives.workspace = true -reth-rlp.workspace = true -reth-rlp-derive = { path = "../../rlp/rlp-derive" } reth-net-common = { path = "../common" } reth-net-nat = { path = "../nat" } # ethereum +alloy-rlp = { workspace = true, features = ["derive"] } discv5.workspace = true secp256k1 = { workspace = true, features = ["global-context", "rand-std", "recovery", "serde"] } enr = { workspace = true, default-features = false, features = ["rust-secp256k1"] } diff --git a/crates/net/discv4/src/config.rs b/crates/net/discv4/src/config.rs index 2f56835fc68..17ba66d1324 100644 --- a/crates/net/discv4/src/config.rs +++ b/crates/net/discv4/src/config.rs @@ -3,13 +3,13 @@ //! This basis of this file has been taken from the discv5 codebase: //! +use alloy_rlp::Encodable; use reth_net_common::ban_list::BanList; use reth_net_nat::{NatResolver, ResolveNatInterval}; use reth_primitives::{ bytes::{Bytes, BytesMut}, NodeRecord, }; -use reth_rlp::Encodable; use std::{ collections::{HashMap, HashSet}, time::Duration, diff --git a/crates/net/discv4/src/error.rs b/crates/net/discv4/src/error.rs index 804e084ba58..580f0e23d86 100644 --- a/crates/net/discv4/src/error.rs +++ b/crates/net/discv4/src/error.rs @@ -7,7 +7,7 @@ use tokio::sync::{mpsc::error::SendError, oneshot::error::RecvError}; #[allow(missing_docs)] pub enum DecodePacketError { #[error("Failed to rlp decode: {0:?}")] - Rlp(#[from] reth_rlp::DecodeError), + Rlp(#[from] alloy_rlp::Error), #[error("Received packet len too short.")] PacketTooShort, #[error("Hash of the header not equals to the hash of the data.")] diff --git a/crates/net/discv4/src/lib.rs b/crates/net/discv4/src/lib.rs index d748e5671da..ea4cb229e55 100644 --- a/crates/net/discv4/src/lib.rs +++ b/crates/net/discv4/src/lib.rs @@ -33,6 +33,7 @@ use crate::{ error::{DecodePacketError, Discv4Error}, proto::{FindNode, Message, Neighbours, Packet, Ping, Pong}, }; +use alloy_rlp::{RlpDecodable, RlpEncodable}; use discv5::{ kbucket, kbucket::{ @@ -48,7 +49,6 @@ use reth_primitives::{ bytes::{Bytes, BytesMut}, hex, ForkId, PeerId, H256, }; -use reth_rlp::{RlpDecodable, RlpEncodable}; use secp256k1::SecretKey; use std::{ cell::RefCell, @@ -356,7 +356,7 @@ impl Discv4 { /// Sets the pair in the EIP-868 [`Enr`] of the node. /// /// If the key already exists, this will update it. - pub fn set_eip868_rlp(&self, key: Vec, value: impl reth_rlp::Encodable) { + pub fn set_eip868_rlp(&self, key: Vec, value: impl alloy_rlp::Encodable) { let mut buf = BytesMut::new(); value.encode(&mut buf); self.set_eip868_rlp_pair(key, buf.freeze()) @@ -2060,9 +2060,9 @@ impl From for EnrForkIdEntry { mod tests { use super::*; use crate::test_utils::{create_discv4, create_discv4_with_config, rng_endpoint, rng_record}; + use alloy_rlp::{Decodable, Encodable}; use rand::{thread_rng, Rng}; use reth_primitives::{hex, mainnet_nodes, ForkHash}; - use reth_rlp::{Decodable, Encodable}; use std::{future::poll_fn, net::Ipv4Addr}; #[tokio::test] diff --git a/crates/net/discv4/src/proto.rs b/crates/net/discv4/src/proto.rs index 5abe78167c9..05b0be9eb47 100644 --- a/crates/net/discv4/src/proto.rs +++ b/crates/net/discv4/src/proto.rs @@ -1,13 +1,14 @@ #![allow(missing_docs)] use crate::{error::DecodePacketError, EnrForkIdEntry, PeerId, MAX_PACKET_SIZE, MIN_PACKET_SIZE}; +use alloy_rlp::{ + length_of_length, Decodable, Encodable, Error as RlpError, Header, RlpDecodable, RlpEncodable, +}; use enr::{Enr, EnrKey}; use reth_primitives::{ bytes::{Buf, BufMut, Bytes, BytesMut}, keccak256, ForkId, NodeRecord, H256, }; -use reth_rlp::{length_of_length, Decodable, DecodeError, Encodable, Header}; -use reth_rlp_derive::{RlpDecodable, RlpEncodable}; use secp256k1::{ ecdsa::{RecoverableSignature, RecoveryId}, SecretKey, SECP256K1, @@ -254,24 +255,24 @@ where } impl Decodable for EnrWrapper { - fn decode(buf: &mut &[u8]) -> Result { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { let enr = as rlp::Decodable>::decode(&rlp::Rlp::new(buf)) .map_err(|e| match e { - rlp::DecoderError::RlpIsTooShort => DecodeError::InputTooShort, - rlp::DecoderError::RlpInvalidLength => DecodeError::Overflow, - rlp::DecoderError::RlpExpectedToBeList => DecodeError::UnexpectedString, - rlp::DecoderError::RlpExpectedToBeData => DecodeError::UnexpectedList, + rlp::DecoderError::RlpIsTooShort => RlpError::InputTooShort, + rlp::DecoderError::RlpInvalidLength => RlpError::Overflow, + rlp::DecoderError::RlpExpectedToBeList => RlpError::UnexpectedString, + rlp::DecoderError::RlpExpectedToBeData => RlpError::UnexpectedList, rlp::DecoderError::RlpDataLenWithZeroPrefix | - rlp::DecoderError::RlpListLenWithZeroPrefix => DecodeError::LeadingZero, - rlp::DecoderError::RlpInvalidIndirection => DecodeError::NonCanonicalSize, + rlp::DecoderError::RlpListLenWithZeroPrefix => RlpError::LeadingZero, + rlp::DecoderError::RlpInvalidIndirection => RlpError::NonCanonicalSize, rlp::DecoderError::RlpIncorrectListLen => { - DecodeError::Custom("incorrect list length when decoding rlp") + RlpError::Custom("incorrect list length when decoding rlp") } - rlp::DecoderError::RlpIsTooBig => DecodeError::Custom("rlp is too big"), + rlp::DecoderError::RlpIsTooBig => RlpError::Custom("rlp is too big"), rlp::DecoderError::RlpInconsistentLengthAndData => { - DecodeError::Custom("inconsistent length and data when decoding rlp") + RlpError::Custom("inconsistent length and data when decoding rlp") } - rlp::DecoderError::Custom(s) => DecodeError::Custom(s), + rlp::DecoderError::Custom(s) => RlpError::Custom(s), }) .map(EnrWrapper::new); if enr.is_ok() { @@ -309,22 +310,22 @@ impl EnrResponse { } impl Decodable for EnrResponse { - fn decode(buf: &mut &[u8]) -> Result { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { let b = &mut &**buf; let rlp_head = Header::decode(b)?; if !rlp_head.list { - return Err(DecodeError::UnexpectedString) + return Err(RlpError::UnexpectedString) } // let started_len = b.len(); let this = Self { - request_hash: reth_rlp::Decodable::decode(b)?, + request_hash: alloy_rlp::Decodable::decode(b)?, enr: EnrWrapper::::decode(b)?, }; - // TODO: `Decodable` can be derived once we have native reth_rlp decoding for ENR: + // TODO: `Decodable` can be derived once we have native alloy_rlp decoding for ENR: // Skipping the size check here is fine since the `buf` is the UDP datagram // let consumed = started_len - b.len(); // if consumed != rlp_head.payload_length { - // return Err(reth_rlp::DecodeError::ListLengthMismatch { + // return Err(alloy_rlp::Error::ListLengthMismatch { // expected: rlp_head.payload_length, // got: consumed, // }) @@ -384,11 +385,11 @@ impl Encodable for Ping { } impl Decodable for Ping { - fn decode(buf: &mut &[u8]) -> Result { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { let b = &mut &**buf; let rlp_head = Header::decode(b)?; if !rlp_head.list { - return Err(DecodeError::UnexpectedString) + return Err(RlpError::UnexpectedString) } let started_len = b.len(); let _version = u32::decode(b)?; @@ -406,7 +407,7 @@ impl Decodable for Ping { let consumed = started_len - b.len(); if consumed > rlp_head.payload_length { - return Err(DecodeError::ListLengthMismatch { + return Err(RlpError::ListLengthMismatch { expected: rlp_head.payload_length, got: consumed, }) @@ -455,11 +456,11 @@ impl Encodable for Pong { } impl Decodable for Pong { - fn decode(buf: &mut &[u8]) -> Result { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { let b = &mut &**buf; let rlp_head = Header::decode(b)?; if !rlp_head.list { - return Err(DecodeError::UnexpectedString) + return Err(RlpError::UnexpectedString) } let started_len = b.len(); let mut this = Self { @@ -476,7 +477,7 @@ impl Decodable for Pong { let consumed = started_len - b.len(); if consumed > rlp_head.payload_length { - return Err(DecodeError::ListLengthMismatch { + return Err(RlpError::ListLengthMismatch { expected: rlp_head.payload_length, got: consumed, }) @@ -715,8 +716,8 @@ mod tests { #[test] fn encode_decode_enr_msg() { use self::EnrWrapper; + use alloy_rlp::Decodable; use enr::secp256k1::SecretKey; - use reth_rlp::Decodable; use std::net::Ipv4Addr; let mut rng = rand::rngs::OsRng; @@ -754,8 +755,8 @@ mod tests { #[test] fn encode_known_rlp_enr() { use self::EnrWrapper; + use alloy_rlp::Decodable; use enr::{secp256k1::SecretKey, EnrPublicKey}; - use reth_rlp::Decodable; use std::net::Ipv4Addr; let valid_record = diff --git a/crates/net/dns/Cargo.toml b/crates/net/dns/Cargo.toml index 012fe4548de..f6ed6faf0f3 100644 --- a/crates/net/dns/Cargo.toml +++ b/crates/net/dns/Cargo.toml @@ -12,9 +12,9 @@ description = "Support for EIP-1459 Node Discovery via DNS" # reth reth-primitives.workspace = true reth-net-common = { path = "../common" } -reth-rlp.workspace = true # ethereum +alloy-rlp.workspace = true secp256k1 = { workspace = true, features = ["global-context", "rand-std", "recovery", "serde"] } enr = { workspace = true, default-features = false, features = ["rust-secp256k1"] } diff --git a/crates/net/dns/src/lib.rs b/crates/net/dns/src/lib.rs index b101c8b3ed4..d17f8268a21 100644 --- a/crates/net/dns/src/lib.rs +++ b/crates/net/dns/src/lib.rs @@ -391,7 +391,7 @@ pub enum DnsDiscoveryEvent { /// Converts an [Enr] into a [NodeRecord] fn convert_enr_node_record(enr: &Enr) -> Option { - use reth_rlp::Decodable; + use alloy_rlp::Decodable; let node_record = NodeRecord { address: enr.ip4().map(IpAddr::from).or_else(|| enr.ip6().map(IpAddr::from))?, @@ -411,9 +411,9 @@ fn convert_enr_node_record(enr: &Enr) -> Option mod tests { use super::*; use crate::tree::TreeRootEntry; + use alloy_rlp::Encodable; use enr::{EnrBuilder, EnrKey}; use reth_primitives::{Chain, Hardfork, MAINNET}; - use reth_rlp::Encodable; use secp256k1::rand::thread_rng; use std::{future::poll_fn, net::Ipv4Addr}; use tokio_stream::StreamExt; diff --git a/crates/net/downloaders/Cargo.toml b/crates/net/downloaders/Cargo.toml index 3c33ab23d84..b56b3054723 100644 --- a/crates/net/downloaders/Cargo.toml +++ b/crates/net/downloaders/Cargo.toml @@ -33,7 +33,7 @@ rayon.workspace = true thiserror.workspace = true # optional deps for the test-utils feature -reth-rlp = { workspace = true, optional = true } +alloy-rlp = { workspace = true, optional = true } tempfile = { version = "3.3", optional = true } itertools = { workspace = true, optional = true } @@ -44,10 +44,10 @@ reth-tracing = { path = "../../tracing" } assert_matches.workspace = true tokio = { workspace = true, features = ["macros", "rt-multi-thread"] } -reth-rlp.workspace = true +alloy-rlp.workspace = true itertools.workspace = true tempfile = "3.3" [features] -test-utils = ["dep:reth-rlp", "dep:tempfile", "dep:itertools"] +test-utils = ["dep:alloy-rlp", "dep:tempfile", "dep:itertools"] diff --git a/crates/net/downloaders/src/test_utils/file_client.rs b/crates/net/downloaders/src/test_utils/file_client.rs index 11135264cd6..6ca0880bff4 100644 --- a/crates/net/downloaders/src/test_utils/file_client.rs +++ b/crates/net/downloaders/src/test_utils/file_client.rs @@ -1,4 +1,5 @@ use super::file_codec::BlockFileCodec; +use alloy_rlp::{Decodable, Header as RlpHeader}; use itertools::Either; use reth_interfaces::{ p2p::{ @@ -14,7 +15,6 @@ use reth_primitives::{ Block, BlockBody, BlockHash, BlockHashOrNumber, BlockNumber, Header, HeadersDirection, PeerId, H256, }; -use reth_rlp::{Decodable, Header as RlpHeader}; use std::{ collections::HashMap, iter::zip, @@ -65,7 +65,7 @@ pub enum FileClientError { /// An error occurred when decoding blocks, headers, or rlp headers from the file. #[error(transparent)] - Rlp(#[from] reth_rlp::DecodeError), + Rlp(#[from] alloy_rlp::Error), } impl FileClient { @@ -255,6 +255,7 @@ mod tests { headers::{reverse_headers::ReverseHeadersDownloaderBuilder, test_utils::child_header}, test_utils::{generate_bodies, generate_bodies_file}, }; + use alloy_rlp::Encodable; use assert_matches::assert_matches; use futures::SinkExt; use futures_util::stream::StreamExt; @@ -267,7 +268,6 @@ mod tests { test_utils::TestConsensus, }; use reth_primitives::SealedHeader; - use reth_rlp::Encodable; use std::{ io::{Read, Seek, SeekFrom, Write}, sync::Arc, diff --git a/crates/net/downloaders/src/test_utils/file_codec.rs b/crates/net/downloaders/src/test_utils/file_codec.rs index 98388be4ad7..443877026b2 100644 --- a/crates/net/downloaders/src/test_utils/file_codec.rs +++ b/crates/net/downloaders/src/test_utils/file_codec.rs @@ -1,17 +1,17 @@ //! Codec for reading raw block bodies from a file. use super::FileClientError; +use alloy_rlp::{Decodable, Encodable}; use reth_primitives::{ bytes::{Buf, BytesMut}, Block, }; -use reth_rlp::{Decodable, Encodable}; use tokio_util::codec::{Decoder, Encoder}; /// Codec for reading raw block bodies from a file. /// /// If using with [`FramedRead`](tokio_util::codec::FramedRead), the user should make sure the /// framed reader has capacity for the entire block file. Otherwise, the decoder will return -/// [`InputTooShort`](reth_rlp::DecodeError::InputTooShort), because RLP headers can only be +/// [`InputTooShort`](alloy_rlp::Error::InputTooShort), because RLP headers can only be /// decoded if the internal buffer is large enough to contain the entire block body. /// /// Without ensuring the framed reader has capacity for the entire file, a block body is likely to diff --git a/crates/net/ecies/Cargo.toml b/crates/net/ecies/Cargo.toml index 72525ac4db3..615dd038742 100644 --- a/crates/net/ecies/Cargo.toml +++ b/crates/net/ecies/Cargo.toml @@ -8,10 +8,10 @@ homepage.workspace = true repository.workspace = true [dependencies] -reth-rlp = { workspace = true, features = ["derive", "ethereum-types", "std"] } reth-primitives.workspace = true reth-net-common = { path = "../common" } +alloy-rlp = { workspace = true, features = ["derive"] } futures.workspace = true thiserror.workspace = true tokio = { workspace = true, features = ["full"] } diff --git a/crates/net/ecies/src/algorithm.rs b/crates/net/ecies/src/algorithm.rs index a602d983343..6733ec0da02 100644 --- a/crates/net/ecies/src/algorithm.rs +++ b/crates/net/ecies/src/algorithm.rs @@ -6,6 +6,7 @@ use crate::{ ECIESError, }; use aes::{cipher::StreamCipher, Aes128, Aes256}; +use alloy_rlp::{Encodable, Rlp, RlpEncodable, RlpMaxEncodedLen}; use byteorder::{BigEndian, ByteOrder, ReadBytesExt}; use ctr::Ctr64BE; use digest::{crypto_common::KeyIvInit, Digest}; @@ -15,7 +16,6 @@ use reth_primitives::{ bytes::{BufMut, Bytes, BytesMut}, H128, H256, H512 as PeerId, }; -use reth_rlp::{Encodable, Rlp, RlpEncodable, RlpMaxEncodedLen}; use secp256k1::{ ecdsa::{RecoverableSignature, RecoveryId}, PublicKey, SecretKey, SECP256K1, @@ -352,7 +352,7 @@ impl ECIES { protocol_version: u8, } - reth_rlp::encode_fixed_size(&S { + alloy_rlp::encode_fixed_size(&S { id: pk2id(&self.ephemeral_public_key), nonce: self.nonce, protocol_version: PROTOCOL_VERSION as u8, diff --git a/crates/net/ecies/src/error.rs b/crates/net/ecies/src/error.rs index f4281ffad97..1a2a738c4b0 100644 --- a/crates/net/ecies/src/error.rs +++ b/crates/net/ecies/src/error.rs @@ -63,7 +63,7 @@ pub enum ECIESErrorImpl { Secp256k1(secp256k1::Error), /// Error when decoding RLP data #[error(transparent)] - RLPDecoding(reth_rlp::DecodeError), + RLPDecoding(alloy_rlp::Error), /// Error when converting to integer #[error(transparent)] FromInt(std::num::TryFromIntError), @@ -111,8 +111,8 @@ impl From for ECIESError { } } -impl From for ECIESError { - fn from(source: reth_rlp::DecodeError) -> Self { +impl From for ECIESError { + fn from(source: alloy_rlp::Error) -> Self { ECIESErrorImpl::RLPDecoding(source).into() } } diff --git a/crates/net/eth-wire/Cargo.toml b/crates/net/eth-wire/Cargo.toml index 2eca9eb0d76..36164895999 100644 --- a/crates/net/eth-wire/Cargo.toml +++ b/crates/net/eth-wire/Cargo.toml @@ -9,15 +9,11 @@ homepage.workspace = true repository.workspace = true [dependencies] -bytes.workspace = true -thiserror.workspace = true -serde = { workspace = true, optional = true } - # reth reth-codecs = { path = "../../storage/codecs" } reth-primitives.workspace = true reth-ecies = { path = "../ecies" } -reth-rlp = { workspace = true, features = ["alloc", "derive", "std", "ethereum-types", "smol_str"] } +alloy-rlp = { workspace = true, features = ["derive", "smol_str"] } reth-discv4 = { path = "../discv4" } # metrics @@ -27,6 +23,9 @@ metrics.workspace = true # used for Chain and builders ethers-core = { workspace = true, default-features = false } +bytes.workspace = true +thiserror.workspace = true +serde = { workspace = true, optional = true } tokio = { workspace = true, features = ["full"] } tokio-util = { workspace = true, features = ["io", "codec"] } futures.workspace = true diff --git a/crates/net/eth-wire/src/capability.rs b/crates/net/eth-wire/src/capability.rs index fd528d2fe77..826ff27e2b4 100644 --- a/crates/net/eth-wire/src/capability.rs +++ b/crates/net/eth-wire/src/capability.rs @@ -1,9 +1,9 @@ //! All capability related types use crate::{version::ParseVersionError, EthMessage, EthVersion}; +use alloy_rlp::{Decodable, Encodable, RlpDecodable, RlpEncodable}; use reth_codecs::add_arbitrary_tests; use reth_primitives::bytes::{BufMut, Bytes}; -use reth_rlp::{Decodable, DecodeError, Encodable, RlpDecodable, RlpEncodable}; use smol_str::SmolStr; use std::fmt; @@ -169,7 +169,7 @@ impl Encodable for Capabilities { } impl Decodable for Capabilities { - fn decode(buf: &mut &[u8]) -> Result { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { let inner = Vec::::decode(buf)?; Ok(Self { diff --git a/crates/net/eth-wire/src/disconnect.rs b/crates/net/eth-wire/src/disconnect.rs index 8879cc277d8..8e51cfe4f49 100644 --- a/crates/net/eth-wire/src/disconnect.rs +++ b/crates/net/eth-wire/src/disconnect.rs @@ -1,10 +1,10 @@ //! Disconnect +use alloy_rlp::{Decodable, Encodable, Error as RlpError, Header}; use futures::{Sink, SinkExt}; use reth_codecs::derive_arbitrary; use reth_ecies::stream::ECIESStream; use reth_primitives::bytes::{Buf, BufMut}; -use reth_rlp::{Decodable, DecodeError, Encodable, Header}; use std::fmt::Display; use thiserror::Error; use tokio::io::AsyncWrite; @@ -119,11 +119,11 @@ impl Encodable for DisconnectReason { /// The [`Decodable`] implementation for [`DisconnectReason`] supports either a disconnect reason /// encoded a single byte or a RLP list containing the disconnect reason. impl Decodable for DisconnectReason { - fn decode(buf: &mut &[u8]) -> Result { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { if buf.is_empty() { - return Err(DecodeError::InputTooShort) + return Err(RlpError::InputTooShort) } else if buf.len() > 2 { - return Err(DecodeError::Overflow) + return Err(RlpError::Overflow) } if buf.len() > 1 { @@ -131,7 +131,7 @@ impl Decodable for DisconnectReason { // buf[0] is the first (and only) element of the list. let header = Header::decode(buf)?; if !header.list { - return Err(DecodeError::UnexpectedString) + return Err(RlpError::UnexpectedString) } } @@ -142,7 +142,7 @@ impl Decodable for DisconnectReason { Ok(DisconnectReason::DisconnectRequested) } else { DisconnectReason::try_from(u8::decode(buf)?) - .map_err(|_| DecodeError::Custom("unknown disconnect reason")) + .map_err(|_| RlpError::Custom("unknown disconnect reason")) } } } @@ -189,8 +189,8 @@ where #[cfg(test)] mod tests { use crate::{p2pstream::P2PMessage, DisconnectReason}; + use alloy_rlp::{Decodable, Encodable}; use reth_primitives::hex; - use reth_rlp::{Decodable, Encodable}; fn all_reasons() -> Vec { vec![ diff --git a/crates/net/eth-wire/src/errors/eth.rs b/crates/net/eth-wire/src/errors/eth.rs index d87fed4ebd4..ae7c7c97d87 100644 --- a/crates/net/eth-wire/src/errors/eth.rs +++ b/crates/net/eth-wire/src/errors/eth.rs @@ -50,8 +50,8 @@ impl From for EthStreamError { } } -impl From for EthStreamError { - fn from(err: reth_rlp::DecodeError) -> Self { +impl From for EthStreamError { + fn from(err: alloy_rlp::Error) -> Self { P2PStreamError::from(err).into() } } diff --git a/crates/net/eth-wire/src/errors/p2p.rs b/crates/net/eth-wire/src/errors/p2p.rs index 3d7a2e7f00c..f323a47c1cd 100644 --- a/crates/net/eth-wire/src/errors/p2p.rs +++ b/crates/net/eth-wire/src/errors/p2p.rs @@ -12,7 +12,7 @@ pub enum P2PStreamError { #[error(transparent)] Io(#[from] io::Error), #[error(transparent)] - Rlp(#[from] reth_rlp::DecodeError), + Rlp(#[from] alloy_rlp::Error), #[error(transparent)] Snap(#[from] snap::Error), #[error(transparent)] @@ -73,7 +73,7 @@ pub enum P2PHandshakeError { #[error("Disconnected by peer: {0}")] Disconnected(DisconnectReason), #[error("error decoding a message during handshake: {0}")] - DecodeError(#[from] reth_rlp::DecodeError), + DecodeError(#[from] alloy_rlp::Error), } /// An error that can occur when interacting with a pinger. diff --git a/crates/net/eth-wire/src/ethstream.rs b/crates/net/eth-wire/src/ethstream.rs index 3c06b10d4ca..9df2b73ab5b 100644 --- a/crates/net/eth-wire/src/ethstream.rs +++ b/crates/net/eth-wire/src/ethstream.rs @@ -4,13 +4,13 @@ use crate::{ types::{EthMessage, ProtocolMessage, Status}, CanDisconnect, DisconnectReason, EthVersion, }; +use alloy_rlp::Encodable; use futures::{ready, Sink, SinkExt, StreamExt}; use pin_project::pin_project; use reth_primitives::{ bytes::{Bytes, BytesMut}, ForkFilter, }; -use reth_rlp::Encodable; use std::{ pin::Pin, task::{Context, Poll}, diff --git a/crates/net/eth-wire/src/hello.rs b/crates/net/eth-wire/src/hello.rs index acbb2c4337d..4b598f7c480 100644 --- a/crates/net/eth-wire/src/hello.rs +++ b/crates/net/eth-wire/src/hello.rs @@ -1,8 +1,8 @@ use crate::{capability::Capability, EthVersion, ProtocolVersion}; +use alloy_rlp::{RlpDecodable, RlpEncodable}; use reth_codecs::derive_arbitrary; use reth_discv4::DEFAULT_DISCOVERY_PORT; use reth_primitives::{constants::RETH_CLIENT_VERSION, PeerId}; -use reth_rlp::{RlpDecodable, RlpEncodable}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -108,9 +108,9 @@ impl HelloMessageBuilder { #[cfg(test)] mod tests { + use alloy_rlp::{Decodable, Encodable, EMPTY_STRING_CODE}; use reth_discv4::DEFAULT_DISCOVERY_PORT; use reth_ecies::util::pk2id; - use reth_rlp::{Decodable, Encodable, EMPTY_STRING_CODE}; use secp256k1::{SecretKey, SECP256K1}; use crate::{ diff --git a/crates/net/eth-wire/src/p2pstream.rs b/crates/net/eth-wire/src/p2pstream.rs index 41781f10207..379b0241671 100644 --- a/crates/net/eth-wire/src/p2pstream.rs +++ b/crates/net/eth-wire/src/p2pstream.rs @@ -6,6 +6,7 @@ use crate::{ pinger::{Pinger, PingerEvent}, DisconnectReason, HelloMessage, }; +use alloy_rlp::{Decodable, Encodable, Error as RlpError, EMPTY_LIST_CODE}; use futures::{Sink, SinkExt, StreamExt}; use pin_project::pin_project; use reth_codecs::derive_arbitrary; @@ -14,7 +15,6 @@ use reth_primitives::{ bytes::{Buf, BufMut, Bytes, BytesMut}, hex, }; -use reth_rlp::{Decodable, DecodeError, Encodable, EMPTY_LIST_CODE}; use std::{ collections::{BTreeSet, HashMap, HashSet, VecDeque}, io, @@ -731,14 +731,14 @@ impl Encodable for P2PMessage { /// The [`Decodable`] implementation for [`P2PMessage::Ping`] and [`P2PMessage::Pong`] expects a /// snappy encoded payload, see [`Encodable`] implementation. impl Decodable for P2PMessage { - fn decode(buf: &mut &[u8]) -> Result { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { /// Removes the snappy prefix from the Ping/Pong buffer - fn advance_snappy_ping_pong_payload(buf: &mut &[u8]) -> Result<(), DecodeError> { + fn advance_snappy_ping_pong_payload(buf: &mut &[u8]) -> alloy_rlp::Result<()> { if buf.len() < 3 { - return Err(DecodeError::InputTooShort) + return Err(RlpError::InputTooShort) } if buf[..3] != [0x01, 0x00, EMPTY_LIST_CODE] { - return Err(DecodeError::Custom("expected snappy payload")) + return Err(RlpError::Custom("expected snappy payload")) } buf.advance(3); Ok(()) @@ -746,7 +746,7 @@ impl Decodable for P2PMessage { let message_id = u8::decode(&mut &buf[..])?; let id = P2PMessageID::try_from(message_id) - .or(Err(DecodeError::Custom("unknown p2p message id")))?; + .or(Err(RlpError::Custom("unknown p2p message id")))?; buf.advance(1); match id { P2PMessageID::Hello => Ok(P2PMessage::Hello(HelloMessage::decode(buf)?)), @@ -827,12 +827,12 @@ impl Encodable for ProtocolVersion { } impl Decodable for ProtocolVersion { - fn decode(buf: &mut &[u8]) -> Result { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { let version = u8::decode(buf)?; match version { 4 => Ok(ProtocolVersion::V4), 5 => Ok(ProtocolVersion::V5), - _ => Err(DecodeError::Custom("unknown p2p protocol version")), + _ => Err(RlpError::Custom("unknown p2p protocol version")), } } } diff --git a/crates/net/eth-wire/src/types/blocks.rs b/crates/net/eth-wire/src/types/blocks.rs index e403c1b54bf..e75368d759f 100644 --- a/crates/net/eth-wire/src/types/blocks.rs +++ b/crates/net/eth-wire/src/types/blocks.rs @@ -1,8 +1,8 @@ //! Implements the `GetBlockHeaders`, `GetBlockBodies`, `BlockHeaders`, and `BlockBodies` message //! types. +use alloy_rlp::{RlpDecodable, RlpDecodableWrapper, RlpEncodable, RlpEncodableWrapper}; use reth_codecs::derive_arbitrary; use reth_primitives::{BlockBody, BlockHashOrNumber, Header, HeadersDirection, H256}; -use reth_rlp::{RlpDecodable, RlpDecodableWrapper, RlpEncodable, RlpEncodableWrapper}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -93,11 +93,11 @@ mod test { use crate::types::{ message::RequestPair, BlockBodies, BlockHeaders, GetBlockBodies, GetBlockHeaders, }; + use alloy_rlp::{Decodable, Encodable}; use reth_primitives::{ hex, BlockHashOrNumber, Header, HeadersDirection, Signature, Transaction, TransactionKind, TransactionSigned, TxLegacy, U256, }; - use reth_rlp::{Decodable, Encodable}; use std::str::FromStr; use super::BlockBody; diff --git a/crates/net/eth-wire/src/types/broadcast.rs b/crates/net/eth-wire/src/types/broadcast.rs index 930db5f0315..fe3e5bfa722 100644 --- a/crates/net/eth-wire/src/types/broadcast.rs +++ b/crates/net/eth-wire/src/types/broadcast.rs @@ -1,10 +1,10 @@ //! Types for broadcasting new data. use crate::{EthMessage, EthVersion}; -use reth_codecs::derive_arbitrary; -use reth_primitives::{Block, Bytes, TransactionSigned, H256, U128}; -use reth_rlp::{ +use alloy_rlp::{ Decodable, Encodable, RlpDecodable, RlpDecodableWrapper, RlpEncodable, RlpEncodableWrapper, }; +use reth_codecs::derive_arbitrary; +use reth_primitives::{Block, Bytes, TransactionSigned, H256, U128}; use std::sync::Arc; #[cfg(feature = "serde")] @@ -242,8 +242,8 @@ pub struct NewPooledTransactionHashes68 { /// the following way: /// * `[type_0: B_1, type_1: B_1, ...]` /// - /// This would make it seem like the [`Encodable`](reth_rlp::Encodable) and - /// [`Decodable`](reth_rlp::Decodable) implementations should directly use a `Vec` for + /// This would make it seem like the [`Encodable`](alloy_rlp::Encodable) and + /// [`Decodable`](alloy_rlp::Decodable) implementations should directly use a `Vec` for /// encoding and decoding, because it looks like this field should be encoded as a _list_ of /// bytes. /// @@ -254,7 +254,7 @@ pub struct NewPooledTransactionHashes68 { /// **not** a RLP list. /// /// Because of this, we do not directly use the `Vec` when encoding and decoding, and - /// instead use the [`Encodable`](reth_rlp::Encodable) and [`Decodable`](reth_rlp::Decodable) + /// instead use the [`Encodable`](alloy_rlp::Encodable) and [`Decodable`](alloy_rlp::Decodable) /// implementations for `&[u8]` instead, which encodes into a RLP string, and expects an RLP /// string when decoding. pub types: Vec, @@ -300,7 +300,7 @@ impl Encodable for NewPooledTransactionHashes68 { } impl Decodable for NewPooledTransactionHashes68 { - fn decode(buf: &mut &[u8]) -> Result { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { #[derive(RlpDecodable)] struct EncodableNewPooledTransactionHashes68 { types: Bytes, @@ -316,9 +316,9 @@ impl Decodable for NewPooledTransactionHashes68 { #[cfg(test)] mod tests { use super::*; + use alloy_rlp::{Decodable, Encodable}; use bytes::BytesMut; use reth_primitives::hex; - use reth_rlp::{Decodable, Encodable}; use std::str::FromStr; /// Takes as input a struct / encoded hex message pair, ensuring that we encode to the exact hex diff --git a/crates/net/eth-wire/src/types/message.rs b/crates/net/eth-wire/src/types/message.rs index 1ec770333eb..17efbeb2dfb 100644 --- a/crates/net/eth-wire/src/types/message.rs +++ b/crates/net/eth-wire/src/types/message.rs @@ -5,8 +5,8 @@ use super::{ NewPooledTransactionHashes68, NodeData, PooledTransactions, Receipts, Status, Transactions, }; use crate::{errors::EthStreamError, EthVersion, SharedTransactions}; +use alloy_rlp::{length_of_length, Decodable, Encodable, Header}; use reth_primitives::bytes::{Buf, BufMut}; -use reth_rlp::{length_of_length, Decodable, Encodable, Header}; use std::{fmt::Debug, sync::Arc}; #[cfg(feature = "serde")] @@ -325,8 +325,8 @@ impl Encodable for EthMessageID { } impl Decodable for EthMessageID { - fn decode(buf: &mut &[u8]) -> Result { - let id = buf.first().ok_or(reth_rlp::DecodeError::InputTooShort)?; + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { + let id = buf.first().ok_or(alloy_rlp::Error::InputTooShort)?; let id = match id { 0x00 => EthMessageID::Status, 0x01 => EthMessageID::NewBlockHashes, @@ -343,7 +343,7 @@ impl Decodable for EthMessageID { 0x0e => EthMessageID::NodeData, 0x0f => EthMessageID::GetReceipts, 0x10 => EthMessageID::Receipts, - _ => return Err(reth_rlp::DecodeError::Custom("Invalid message ID")), + _ => return Err(alloy_rlp::Error::Custom("Invalid message ID")), }; buf.advance(1); Ok(id) @@ -393,7 +393,7 @@ impl Encodable for RequestPair where T: Encodable, { - fn encode(&self, out: &mut dyn reth_rlp::BufMut) { + fn encode(&self, out: &mut dyn alloy_rlp::BufMut) { let header = Header { list: true, payload_length: self.request_id.length() + self.message.length() }; @@ -416,7 +416,7 @@ impl Decodable for RequestPair where T: Decodable, { - fn decode(buf: &mut &[u8]) -> Result { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { let _header = Header::decode(buf)?; Ok(Self { request_id: u64::decode(buf)?, message: T::decode(buf)? }) } @@ -428,8 +428,8 @@ mod test { errors::EthStreamError, types::message::RequestPair, EthMessage, EthMessageID, GetNodeData, NodeData, ProtocolMessage, }; + use alloy_rlp::{Decodable, Encodable}; use reth_primitives::hex; - use reth_rlp::{Decodable, Encodable}; fn encode(value: T) -> Vec { let mut buf = vec![]; diff --git a/crates/net/eth-wire/src/types/receipts.rs b/crates/net/eth-wire/src/types/receipts.rs index a3ab468dc28..b009bc305a2 100644 --- a/crates/net/eth-wire/src/types/receipts.rs +++ b/crates/net/eth-wire/src/types/receipts.rs @@ -1,7 +1,7 @@ //! Implements the `GetReceipts` and `Receipts` message types. +use alloy_rlp::{RlpDecodableWrapper, RlpEncodableWrapper}; use reth_codecs::derive_arbitrary; use reth_primitives::{ReceiptWithBloom, H256}; -use reth_rlp::{RlpDecodableWrapper, RlpEncodableWrapper}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -37,8 +37,8 @@ mod test { types::{message::RequestPair, GetReceipts}, Receipts, }; + use alloy_rlp::{Decodable, Encodable}; use reth_primitives::{hex, Log, Receipt, ReceiptWithBloom, TxType}; - use reth_rlp::{Decodable, Encodable}; #[test] fn roundtrip_eip1559() { diff --git a/crates/net/eth-wire/src/types/state.rs b/crates/net/eth-wire/src/types/state.rs index 75b418b2a25..395ce2b5ba7 100644 --- a/crates/net/eth-wire/src/types/state.rs +++ b/crates/net/eth-wire/src/types/state.rs @@ -1,7 +1,7 @@ //! Implements the `GetNodeData` and `NodeData` message types. +use alloy_rlp::{RlpDecodableWrapper, RlpEncodableWrapper}; use reth_codecs::derive_arbitrary; use reth_primitives::{Bytes, H256}; -use reth_rlp::{RlpDecodableWrapper, RlpEncodableWrapper}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -29,7 +29,7 @@ mod test { use reth_primitives::hex; use crate::{message::RequestPair, GetNodeData, NodeData}; - use reth_rlp::{Decodable, Encodable}; + use alloy_rlp::{Decodable, Encodable}; #[test] // Test vector from: https://eips.ethereum.org/EIPS/eip-2481 diff --git a/crates/net/eth-wire/src/types/status.rs b/crates/net/eth-wire/src/types/status.rs index 6e9213010b2..7c0974a850c 100644 --- a/crates/net/eth-wire/src/types/status.rs +++ b/crates/net/eth-wire/src/types/status.rs @@ -1,10 +1,10 @@ use crate::{EthVersion, StatusBuilder}; +use alloy_rlp::{RlpDecodable, RlpEncodable}; use reth_codecs::derive_arbitrary; use reth_primitives::{ hex, Chain, ChainSpec, ForkId, Genesis, Hardfork, Head, H256, MAINNET, U256, }; -use reth_rlp::{RlpDecodable, RlpEncodable}; use std::fmt::{Debug, Display}; #[cfg(feature = "serde")] @@ -148,12 +148,12 @@ impl Default for Status { #[cfg(test)] mod tests { use crate::types::{EthVersion, Status}; + use alloy_rlp::{Decodable, Encodable}; use ethers_core::types::Chain as NamedChain; use rand::Rng; use reth_primitives::{ hex, Chain, ChainSpec, ForkCondition, ForkHash, ForkId, Genesis, Hardfork, Head, H256, U256, }; - use reth_rlp::{Decodable, Encodable}; use std::str::FromStr; #[test] diff --git a/crates/net/eth-wire/src/types/transactions.rs b/crates/net/eth-wire/src/types/transactions.rs index 80b60c439e1..565ffe160e1 100644 --- a/crates/net/eth-wire/src/types/transactions.rs +++ b/crates/net/eth-wire/src/types/transactions.rs @@ -1,7 +1,7 @@ //! Implements the `GetPooledTransactions` and `PooledTransactions` message types. +use alloy_rlp::{RlpDecodableWrapper, RlpEncodableWrapper}; use reth_codecs::derive_arbitrary; use reth_primitives::{PooledTransactionsElement, TransactionSigned, H256}; -use reth_rlp::{RlpDecodableWrapper, RlpEncodableWrapper}; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -48,10 +48,10 @@ impl From> for PooledTransactions { #[cfg(test)] mod test { use crate::{message::RequestPair, GetPooledTransactions, PooledTransactions}; + use alloy_rlp::{Decodable, Encodable}; use reth_primitives::{ hex, Signature, Transaction, TransactionKind, TransactionSigned, TxEip1559, TxLegacy, U256, }; - use reth_rlp::{Decodable, Encodable}; use std::str::FromStr; #[test] diff --git a/crates/net/eth-wire/tests/fuzz_roundtrip.rs b/crates/net/eth-wire/tests/fuzz_roundtrip.rs index 34117e8e130..ed9467d293c 100644 --- a/crates/net/eth-wire/tests/fuzz_roundtrip.rs +++ b/crates/net/eth-wire/tests/fuzz_roundtrip.rs @@ -1,10 +1,10 @@ //! Round-trip encoding fuzzing for the `eth-wire` crate. -use reth_rlp::{Decodable, Encodable}; +use alloy_rlp::{Decodable, Encodable}; use serde::Serialize; use std::fmt::Debug; -/// Creates a fuzz test for a type that should be [`Encodable`](reth_rlp::Encodable) and -/// [`Decodable`](reth_rlp::Decodable). +/// Creates a fuzz test for a type that should be [`Encodable`](alloy_rlp::Encodable) and +/// [`Decodable`](alloy_rlp::Decodable). /// /// The test will create a random instance of the type, encode it, and then decode it. fn roundtrip_encoding(thing: T) @@ -48,6 +48,7 @@ macro_rules! fuzz_type_and_name { #[cfg(any(test, feature = "bench"))] pub mod fuzz_rlp { use crate::roundtrip_encoding; + use alloy_rlp::{RlpDecodableWrapper, RlpEncodableWrapper}; use reth_codecs::derive_arbitrary; use reth_eth_wire::{ BlockBodies, BlockHeaders, DisconnectReason, GetBlockBodies, GetBlockHeaders, GetNodeData, @@ -56,7 +57,6 @@ pub mod fuzz_rlp { PooledTransactions, Receipts, Status, Transactions, }; use reth_primitives::{BlockHashOrNumber, TransactionSigned}; - use reth_rlp::{RlpDecodableWrapper, RlpEncodableWrapper}; use serde::{Deserialize, Serialize}; use test_fuzz::test_fuzz; diff --git a/crates/net/eth-wire/tests/new_block.rs b/crates/net/eth-wire/tests/new_block.rs index 9e011bd8d45..cc22a46973b 100644 --- a/crates/net/eth-wire/tests/new_block.rs +++ b/crates/net/eth-wire/tests/new_block.rs @@ -1,7 +1,7 @@ //! Decoding tests for [`NewBlock`] +use alloy_rlp::Decodable; use reth_eth_wire::NewBlock; use reth_primitives::hex; -use reth_rlp::Decodable; use std::{fs, path::PathBuf}; #[test] diff --git a/crates/net/eth-wire/tests/new_pooled_transactions.rs b/crates/net/eth-wire/tests/new_pooled_transactions.rs index 9f767c2573b..0ed63d60294 100644 --- a/crates/net/eth-wire/tests/new_pooled_transactions.rs +++ b/crates/net/eth-wire/tests/new_pooled_transactions.rs @@ -1,7 +1,7 @@ //! Decoding tests for [`NewPooledTransactions`] +use alloy_rlp::Decodable; use reth_eth_wire::NewPooledTransactionHashes66; use reth_primitives::hex; -use reth_rlp::Decodable; use std::{fs, path::PathBuf}; #[test] diff --git a/crates/net/eth-wire/tests/pooled_transactions.rs b/crates/net/eth-wire/tests/pooled_transactions.rs index a204a93e8cf..268b6a9c34e 100644 --- a/crates/net/eth-wire/tests/pooled_transactions.rs +++ b/crates/net/eth-wire/tests/pooled_transactions.rs @@ -1,7 +1,7 @@ //! Decoding tests for [`PooledTransactions`] +use alloy_rlp::Decodable; use reth_eth_wire::PooledTransactions; use reth_primitives::{hex, Bytes, PooledTransactionsElement}; -use reth_rlp::Decodable; use std::{fs, path::PathBuf}; #[test] diff --git a/crates/net/network/Cargo.toml b/crates/net/network/Cargo.toml index 6fa1ed348a6..6ae2ccdb7c3 100644 --- a/crates/net/network/Cargo.toml +++ b/crates/net/network/Cargo.toml @@ -26,13 +26,13 @@ reth-discv4 = { path = "../discv4" } reth-dns-discovery = { path = "../dns" } reth-eth-wire = { path = "../eth-wire" } reth-ecies = { path = "../ecies" } -reth-rlp.workspace = true -reth-rlp-derive = { path = "../../rlp/rlp-derive" } reth-tasks.workspace = true reth-transaction-pool.workspace = true reth-provider.workspace = true reth-rpc-types.workspace = true +alloy-rlp.workspace = true + # async/futures futures.workspace = true pin-project.workspace = true diff --git a/crates/net/network/src/fetch/client.rs b/crates/net/network/src/fetch/client.rs index 9136ae4df98..ab4dff101b9 100644 --- a/crates/net/network/src/fetch/client.rs +++ b/crates/net/network/src/fetch/client.rs @@ -16,10 +16,7 @@ use std::sync::{ atomic::{AtomicUsize, Ordering}, Arc, }; -use tokio::sync::{ - mpsc::UnboundedSender, - oneshot::{self}, -}; +use tokio::sync::{mpsc::UnboundedSender, oneshot}; /// Front-end API for fetching data from the network. /// diff --git a/crates/net/network/src/transactions.rs b/crates/net/network/src/transactions.rs index 19e4918ea5d..ff8e4363d0f 100644 --- a/crates/net/network/src/transactions.rs +++ b/crates/net/network/src/transactions.rs @@ -894,11 +894,11 @@ pub enum NetworkTransactionEvent { mod tests { use super::*; use crate::{test_utils::Testnet, NetworkConfigBuilder, NetworkManager}; + use alloy_rlp::Decodable; use reth_interfaces::sync::{NetworkSyncUpdater, SyncState}; use reth_network_api::NetworkInfo; use reth_primitives::hex; use reth_provider::test_utils::NoopProvider; - use reth_rlp::Decodable; use reth_transaction_pool::test_utils::{testing_pool, MockTransaction}; use secp256k1::SecretKey; use std::future::poll_fn; diff --git a/crates/payload/basic/Cargo.toml b/crates/payload/basic/Cargo.toml index c6d505b6d0b..5ae986c40c9 100644 --- a/crates/payload/basic/Cargo.toml +++ b/crates/payload/basic/Cargo.toml @@ -13,13 +13,13 @@ description = "A basic payload builder for reth that uses the txpool API to buil reth-primitives.workspace = true reth-revm = { path = "../../revm" } reth-transaction-pool.workspace = true -reth-rlp.workspace = true reth-provider.workspace = true reth-payload-builder.workspace = true reth-tasks.workspace = true reth-interfaces.workspace = true ## ethereum +alloy-rlp.workspace = true revm.workspace = true ## async diff --git a/crates/payload/basic/src/lib.rs b/crates/payload/basic/src/lib.rs index 2f72b1fe6d9..db978a82f2f 100644 --- a/crates/payload/basic/src/lib.rs +++ b/crates/payload/basic/src/lib.rs @@ -14,6 +14,7 @@ //! A basic payload generator for reth. use crate::metrics::PayloadBuilderMetrics; +use alloy_rlp::Encodable; use futures_core::ready; use futures_util::FutureExt; use reth_interfaces::{RethError, RethResult}; @@ -38,7 +39,6 @@ use reth_revm::{ into_reth_log, state_change::{apply_beacon_root_contract_call, post_block_withdrawals_balance_increments}, }; -use reth_rlp::Encodable; use reth_tasks::TaskSpawner; use reth_transaction_pool::TransactionPool; use revm::{ diff --git a/crates/payload/builder/Cargo.toml b/crates/payload/builder/Cargo.toml index 7f2c9bcaae1..05c0abe016a 100644 --- a/crates/payload/builder/Cargo.toml +++ b/crates/payload/builder/Cargo.toml @@ -12,13 +12,13 @@ description = "reth payload builder" ## reth reth-primitives.workspace = true reth-rpc-types.workspace = true -reth-rlp.workspace = true reth-transaction-pool.workspace = true reth-interfaces.workspace = true reth-revm-primitives = { path = "../../revm/revm-primitives" } reth-rpc-types-compat.workspace = true ## ethereum +alloy-rlp.workspace = true revm-primitives.workspace = true ## async diff --git a/crates/payload/builder/src/payload.rs b/crates/payload/builder/src/payload.rs index e20d109cf26..a9ff4bd6cc1 100644 --- a/crates/payload/builder/src/payload.rs +++ b/crates/payload/builder/src/payload.rs @@ -1,10 +1,10 @@ //! Contains types required for building a payload. +use alloy_rlp::Encodable; use reth_primitives::{ Address, BlobTransactionSidecar, ChainSpec, Header, SealedBlock, Withdrawal, H256, U256, }; use reth_revm_primitives::config::revm_spec_by_timestamp_after_merge; -use reth_rlp::Encodable; use reth_rpc_types::engine::{ ExecutionPayloadEnvelopeV2, ExecutionPayloadEnvelopeV3, ExecutionPayloadV1, PayloadAttributes, PayloadId, diff --git a/crates/primitives/Cargo.toml b/crates/primitives/Cargo.toml index 8214b1cc2f9..678cea1c75a 100644 --- a/crates/primitives/Cargo.toml +++ b/crates/primitives/Cargo.toml @@ -10,13 +10,12 @@ description = "Commonly used types in reth." [dependencies] # reth -reth-rlp = { workspace = true, features = ["std", "derive", "ethereum-types"] } -reth-rlp-derive = { path = "../rlp/rlp-derive" } reth-codecs = { path = "../storage/codecs" } revm-primitives = { workspace = true, features = ["serde"] } # ethereum -alloy-primitives = { workspace = true, features = ["std", "rand"] } +alloy-primitives = { workspace = true, features = ["rand", "rlp"] } +alloy-rlp = { workspace = true, features = ["arrayvec"] } ethers-core = { workspace = true, default-features = false } ruint = { version = "1.9.0", features = ["primitive-types", "rlp"] } diff --git a/crates/primitives/benches/recover_ecdsa_crit.rs b/crates/primitives/benches/recover_ecdsa_crit.rs index 24f8b2acde1..57893faa9f7 100644 --- a/crates/primitives/benches/recover_ecdsa_crit.rs +++ b/crates/primitives/benches/recover_ecdsa_crit.rs @@ -1,7 +1,7 @@ +use alloy_rlp::Decodable; use criterion::{criterion_group, criterion_main, Criterion}; use pprof::criterion::{Output, PProfProfiler}; use reth_primitives::{hex_literal::hex, TransactionSigned}; -use reth_rlp::Decodable; /// Benchmarks the recovery of the public key from the ECDSA message using criterion. pub fn criterion_benchmark(c: &mut Criterion) { diff --git a/crates/primitives/benches/trie_root.rs b/crates/primitives/benches/trie_root.rs index fe0bd2f8423..6f76abed4f9 100644 --- a/crates/primitives/benches/trie_root.rs +++ b/crates/primitives/benches/trie_root.rs @@ -53,12 +53,12 @@ criterion_main!(benches); mod implementations { use super::*; + use alloy_rlp::Encodable; use bytes::BytesMut; use reth_primitives::{ proofs::adjust_index_for_rlp, trie::{HashBuilder, Nibbles}, }; - use reth_rlp::Encodable; use std::vec::IntoIter; pub fn trie_hash_ordered_trie_root(receipts: IntoIter) -> H256 { diff --git a/crates/primitives/src/block.rs b/crates/primitives/src/block.rs index 5f2cdf669be..ed11a2f0587 100644 --- a/crates/primitives/src/block.rs +++ b/crates/primitives/src/block.rs @@ -1,8 +1,8 @@ use crate::{ Address, BlockHash, BlockNumber, Header, SealedHeader, TransactionSigned, Withdrawal, H256, U64, }; +use alloy_rlp::{Decodable, Encodable, Error as RlpError, RlpDecodable, RlpEncodable}; use reth_codecs::derive_arbitrary; -use reth_rlp::{Decodable, DecodeError, Encodable, RlpDecodable, RlpEncodable}; use serde::{ de::{MapAccess, Visitor}, ser::SerializeStruct, @@ -317,8 +317,8 @@ impl Encodable for BlockHashOrNumber { /// Allows for RLP decoding of a block hash or block number impl Decodable for BlockHashOrNumber { - fn decode(buf: &mut &[u8]) -> Result { - let header: u8 = *buf.first().ok_or(DecodeError::InputTooShort)?; + 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 // 0xa0 = 0x80 (start of string) + 0x20 (32, length of string) if header == 0xa0 { diff --git a/crates/primitives/src/chain/mod.rs b/crates/primitives/src/chain/mod.rs index bb1c877bd3e..7082151af8e 100644 --- a/crates/primitives/src/chain/mod.rs +++ b/crates/primitives/src/chain/mod.rs @@ -3,8 +3,8 @@ use crate::{ net::{goerli_nodes, mainnet_nodes, sepolia_nodes}, NodeRecord, U256, U64, }; +use alloy_rlp::{Decodable, Encodable}; use reth_codecs::add_arbitrary_tests; -use reth_rlp::{Decodable, Encodable}; use serde::{Deserialize, Serialize}; use std::{fmt, str::FromStr}; @@ -180,7 +180,7 @@ impl FromStr for Chain { } impl Encodable for Chain { - fn encode(&self, out: &mut dyn reth_rlp::BufMut) { + fn encode(&self, out: &mut dyn alloy_rlp::BufMut) { match self { Self::Named(chain) => u64::from(*chain).encode(out), Self::Id(id) => id.encode(out), @@ -195,7 +195,7 @@ impl Encodable for Chain { } impl Decodable for Chain { - fn decode(buf: &mut &[u8]) -> Result { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { Ok(u64::decode(buf)?.into()) } } diff --git a/crates/primitives/src/chain/spec.rs b/crates/primitives/src/chain/spec.rs index e5ff3979e5c..7c6b0344a89 100644 --- a/crates/primitives/src/chain/spec.rs +++ b/crates/primitives/src/chain/spec.rs @@ -1131,9 +1131,9 @@ mod tests { ChainSpecBuilder, DisplayHardforks, ForkCondition, ForkHash, ForkId, Genesis, Hardfork, Head, DEV, GOERLI, H256, HOLESKY, MAINNET, SEPOLIA, U256, }; + use alloy_rlp::Encodable; use bytes::BytesMut; use ethers_core::types::Chain as EthersChain; - use reth_rlp::Encodable; use std::str::FromStr; fn test_fork_ids(spec: &ChainSpec, cases: &[(Head, ForkId)]) { diff --git a/crates/primitives/src/forkid.rs b/crates/primitives/src/forkid.rs index 0aad13534ae..de4c3c9f32d 100644 --- a/crates/primitives/src/forkid.rs +++ b/crates/primitives/src/forkid.rs @@ -5,9 +5,9 @@ #![deny(missing_docs)] use crate::{hex, BlockNumber, Head, H256}; +use alloy_rlp::*; use crc::*; use reth_codecs::derive_arbitrary; -use reth_rlp::*; use serde::{Deserialize, Serialize}; use std::{ cmp::Ordering, diff --git a/crates/primitives/src/genesis.rs b/crates/primitives/src/genesis.rs index 91f50e10ff4..fb2741d2352 100644 --- a/crates/primitives/src/genesis.rs +++ b/crates/primitives/src/genesis.rs @@ -5,7 +5,7 @@ use crate::{ utils::serde_helpers::{deserialize_stringified_u64, deserialize_stringified_u64_opt}, Account, Address, Bytes, H256, KECCAK_EMPTY, U256, }; -use reth_rlp::{encode_fixed_size, length_of_length, Encodable, Header as RlpHeader}; +use alloy_rlp::{encode_fixed_size, length_of_length, Encodable, Header as RlpHeader}; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use triehash::sec_trie_root; diff --git a/crates/primitives/src/header.rs b/crates/primitives/src/header.rs index 8ff58a85b7b..a0ae08c21a1 100644 --- a/crates/primitives/src/header.rs +++ b/crates/primitives/src/header.rs @@ -6,9 +6,9 @@ use crate::{ Address, BaseFeeParams, BlockBodyRoots, BlockHash, BlockNumHash, BlockNumber, Bloom, Bytes, H256, H64, U256, }; +use alloy_rlp::{length_of_length, Decodable, Encodable, EMPTY_LIST_CODE, EMPTY_STRING_CODE}; use bytes::{Buf, BufMut, BytesMut}; use reth_codecs::{add_arbitrary_tests, derive_arbitrary, main_codec, Compact}; -use reth_rlp::{length_of_length, Decodable, Encodable, EMPTY_LIST_CODE, EMPTY_STRING_CODE}; use serde::{Deserialize, Serialize}; use std::{ mem, @@ -322,7 +322,7 @@ impl Header { impl Encodable for Header { fn encode(&self, out: &mut dyn BufMut) { let list_header = - reth_rlp::Header { list: true, payload_length: self.header_payload_length() }; + alloy_rlp::Header { list: true, payload_length: self.header_payload_length() }; list_header.encode(out); self.parent_hash.encode(out); self.ommers_hash.encode(out); @@ -400,10 +400,10 @@ impl Encodable for Header { } impl Decodable for Header { - fn decode(buf: &mut &[u8]) -> Result { - let rlp_head = reth_rlp::Header::decode(buf)?; + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { + let rlp_head = alloy_rlp::Header::decode(buf)?; if !rlp_head.list { - return Err(reth_rlp::DecodeError::UnexpectedString) + return Err(alloy_rlp::Error::UnexpectedString) } let started_len = buf.len(); let mut this = Self { @@ -476,7 +476,7 @@ impl Decodable for Header { let consumed = started_len - buf.len(); if consumed != rlp_head.payload_length { - return Err(reth_rlp::DecodeError::ListLengthMismatch { + return Err(alloy_rlp::Error::ListLengthMismatch { expected: rlp_head.payload_length, got: consumed, }) @@ -556,7 +556,7 @@ impl Encodable for SealedHeader { } impl Decodable for SealedHeader { - fn decode(buf: &mut &[u8]) -> Result { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { let b = &mut &**buf; let started_len = buf.len(); @@ -651,7 +651,7 @@ impl Encodable for HeadersDirection { } impl Decodable for HeadersDirection { - fn decode(buf: &mut &[u8]) -> Result { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { let value: bool = Decodable::decode(buf)?; Ok(value.into()) } diff --git a/crates/primitives/src/log.rs b/crates/primitives/src/log.rs index 5d726edd115..d7eed1f0c18 100644 --- a/crates/primitives/src/log.rs +++ b/crates/primitives/src/log.rs @@ -1,6 +1,6 @@ use crate::{Address, Bloom, Bytes, H256}; +use alloy_rlp::{RlpDecodable, RlpEncodable}; use reth_codecs::{main_codec, Compact}; -use reth_rlp::{RlpDecodable, RlpEncodable}; /// Ethereum Log #[main_codec(rlp)] diff --git a/crates/primitives/src/net.rs b/crates/primitives/src/net.rs index bc4d0e84335..eeec5abae03 100644 --- a/crates/primitives/src/net.rs +++ b/crates/primitives/src/net.rs @@ -1,6 +1,5 @@ use crate::PeerId; -use reth_rlp::RlpDecodable; -use reth_rlp_derive::RlpEncodable; +use alloy_rlp::{RlpDecodable, RlpEncodable}; use secp256k1::{SecretKey, SECP256K1}; use serde_with::{DeserializeFromStr, SerializeDisplay}; use std::{ @@ -232,9 +231,9 @@ impl FromStr for NodeRecord { #[cfg(test)] mod tests { use super::*; + use alloy_rlp::{Decodable, Encodable}; use bytes::BytesMut; use rand::{thread_rng, Rng, RngCore}; - use reth_rlp::{Decodable, Encodable}; #[test] fn test_mapped_ipv6() { diff --git a/crates/primitives/src/proofs.rs b/crates/primitives/src/proofs.rs index 1a60ef2d403..5c050f3be3d 100644 --- a/crates/primitives/src/proofs.rs +++ b/crates/primitives/src/proofs.rs @@ -6,10 +6,10 @@ use crate::{ Address, Bytes, GenesisAccount, Header, Log, ReceiptWithBloom, ReceiptWithBloomRef, TransactionSigned, Withdrawal, H256, }; +use alloy_rlp::Encodable; use bytes::{BufMut, BytesMut}; use hash_db::Hasher; use plain_hasher::PlainHasher; -use reth_rlp::Encodable; use revm_primitives::b256; use std::collections::HashMap; use triehash::sec_trie_root; @@ -114,7 +114,7 @@ where pub fn calculate_log_root(logs: &[Log]) -> H256 { //https://github.com/ethereum/go-ethereum/blob/356bbe343a30789e77bb38f25983c8f2f2bfbb47/cmd/evm/internal/t8ntool/execution.go#L255 let mut logs_rlp = Vec::new(); - reth_rlp::encode_list(logs, &mut logs_rlp); + alloy_rlp::encode_list(logs, &mut logs_rlp); keccak256(logs_rlp) } @@ -122,7 +122,7 @@ pub fn calculate_log_root(logs: &[Log]) -> H256 { pub fn calculate_ommers_root(ommers: &[Header]) -> H256 { // RLP Encode let mut ommers_rlp = Vec::new(); - reth_rlp::encode_list(ommers, &mut ommers_rlp); + alloy_rlp::encode_list(ommers, &mut ommers_rlp); keccak256(ommers_rlp) } @@ -147,7 +147,7 @@ mod tests { Address, Block, GenesisAccount, Log, Receipt, ReceiptWithBloom, TxType, H256, U256, }; use alloy_primitives::bloom; - use reth_rlp::Decodable; + use alloy_rlp::Decodable; use revm_primitives::b256; use std::{collections::HashMap, str::FromStr}; diff --git a/crates/primitives/src/receipt.rs b/crates/primitives/src/receipt.rs index 602798f6e08..61a4c079981 100644 --- a/crates/primitives/src/receipt.rs +++ b/crates/primitives/src/receipt.rs @@ -2,9 +2,9 @@ use crate::{ compression::{RECEIPT_COMPRESSOR, RECEIPT_DECOMPRESSOR}, logs_bloom, Bloom, Log, TxType, }; +use alloy_rlp::{length_of_length, Decodable, Encodable}; use bytes::{Buf, BufMut, BytesMut}; use reth_codecs::{main_codec, Compact, CompactZstd}; -use reth_rlp::{length_of_length, Decodable, Encodable}; use std::cmp::Ordering; /// Receipt containing result of transaction execution. @@ -89,23 +89,23 @@ impl ReceiptWithBloom { } /// Decodes the receipt payload - fn decode_receipt(buf: &mut &[u8], tx_type: TxType) -> Result { + fn decode_receipt(buf: &mut &[u8], tx_type: TxType) -> alloy_rlp::Result { let b = &mut &**buf; - let rlp_head = reth_rlp::Header::decode(b)?; + let rlp_head = alloy_rlp::Header::decode(b)?; if !rlp_head.list { - return Err(reth_rlp::DecodeError::UnexpectedString) + return Err(alloy_rlp::Error::UnexpectedString) } let started_len = b.len(); - let success = reth_rlp::Decodable::decode(b)?; - let cumulative_gas_used = reth_rlp::Decodable::decode(b)?; + let success = alloy_rlp::Decodable::decode(b)?; + let cumulative_gas_used = alloy_rlp::Decodable::decode(b)?; let bloom = Decodable::decode(b)?; - let logs = reth_rlp::Decodable::decode(b)?; + let logs = alloy_rlp::Decodable::decode(b)?; let this = Self { receipt: Receipt { tx_type, success, cumulative_gas_used, logs }, bloom }; let consumed = started_len - b.len(); if consumed != rlp_head.payload_length { - return Err(reth_rlp::DecodeError::ListLengthMismatch { + return Err(alloy_rlp::Error::ListLengthMismatch { expected: rlp_head.payload_length, got: consumed, }) @@ -125,19 +125,19 @@ impl Encodable for ReceiptWithBloom { } impl Decodable for ReceiptWithBloom { - fn decode(buf: &mut &[u8]) -> Result { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { // a receipt is either encoded as a string (non legacy) or a list (legacy). // We should not consume the buffer if we are decoding a legacy receipt, so let's // check if the first byte is between 0x80 and 0xbf. let rlp_type = *buf .first() - .ok_or(reth_rlp::DecodeError::Custom("cannot decode a receipt from empty bytes"))?; + .ok_or(alloy_rlp::Error::Custom("cannot decode a receipt from empty bytes"))?; - match rlp_type.cmp(&reth_rlp::EMPTY_LIST_CODE) { + match rlp_type.cmp(&alloy_rlp::EMPTY_LIST_CODE) { Ordering::Less => { // strip out the string header - let _header = reth_rlp::Header::decode(buf)?; - let receipt_type = *buf.first().ok_or(reth_rlp::DecodeError::Custom( + let _header = alloy_rlp::Header::decode(buf)?; + let receipt_type = *buf.first().ok_or(alloy_rlp::Error::Custom( "typed receipt cannot be decoded from an empty slice", ))?; if receipt_type == 0x01 { @@ -150,11 +150,11 @@ impl Decodable for ReceiptWithBloom { buf.advance(1); Self::decode_receipt(buf, TxType::EIP4844) } else { - Err(reth_rlp::DecodeError::Custom("invalid receipt type")) + Err(alloy_rlp::Error::Custom("invalid receipt type")) } } Ordering::Equal => { - Err(reth_rlp::DecodeError::Custom("an empty list is not a valid receipt encoding")) + Err(alloy_rlp::Error::Custom("an empty list is not a valid receipt encoding")) } Ordering::Greater => Self::decode_receipt(buf, TxType::Legacy), } @@ -210,8 +210,8 @@ struct ReceiptWithBloomEncoder<'a> { impl<'a> ReceiptWithBloomEncoder<'a> { /// Returns the rlp header for the receipt payload. - fn receipt_rlp_header(&self) -> reth_rlp::Header { - let mut rlp_head = reth_rlp::Header { list: true, payload_length: 0 }; + fn receipt_rlp_header(&self) -> alloy_rlp::Header { + let mut rlp_head = alloy_rlp::Header { list: true, payload_length: 0 }; rlp_head.payload_length += self.receipt.success.length(); rlp_head.payload_length += self.receipt.cumulative_gas_used.length(); @@ -242,7 +242,7 @@ impl<'a> ReceiptWithBloomEncoder<'a> { if with_header { let payload_length = payload.len() + 1; - let header = reth_rlp::Header { list: false, payload_length }; + let header = alloy_rlp::Header { list: false, payload_length }; header.encode(out); } @@ -290,7 +290,7 @@ mod tests { use super::*; use crate::hex_literal::hex; use alloy_primitives::{address, b256, bytes, Bytes}; - use reth_rlp::{Decodable, Encodable}; + use alloy_rlp::{Decodable, Encodable}; // Test vector from: https://eips.ethereum.org/EIPS/eip-2481 #[test] diff --git a/crates/primitives/src/transaction/access_list.rs b/crates/primitives/src/transaction/access_list.rs index 11b119898a5..393ea8257e9 100644 --- a/crates/primitives/src/transaction/access_list.rs +++ b/crates/primitives/src/transaction/access_list.rs @@ -1,8 +1,8 @@ use std::mem; use crate::{Address, H256}; +use alloy_rlp::{RlpDecodable, RlpDecodableWrapper, RlpEncodable, RlpEncodableWrapper}; use reth_codecs::{main_codec, Compact}; -use reth_rlp::{RlpDecodable, RlpDecodableWrapper, RlpEncodable, RlpEncodableWrapper}; use revm_primitives::U256; use serde::{Deserialize, Serialize}; diff --git a/crates/primitives/src/transaction/eip1559.rs b/crates/primitives/src/transaction/eip1559.rs index fd1d2cd818b..6d758934030 100644 --- a/crates/primitives/src/transaction/eip1559.rs +++ b/crates/primitives/src/transaction/eip1559.rs @@ -1,8 +1,8 @@ use super::access_list::AccessList; use crate::{keccak256, Bytes, ChainId, Signature, TransactionKind, TxType, H256}; +use alloy_rlp::{length_of_length, Decodable, Encodable, Header}; use bytes::BytesMut; use reth_codecs::{main_codec, Compact}; -use reth_rlp::{length_of_length, Decodable, DecodeError, Encodable, Header}; use std::mem; /// A transaction with a priority fee ([EIP-1559](https://eips.ethereum.org/EIPS/eip-1559)). @@ -98,7 +98,7 @@ impl TxEip1559 { /// - `value` /// - `data` (`input`) /// - `access_list` - pub(crate) fn decode_inner(buf: &mut &[u8]) -> Result { + pub(crate) fn decode_inner(buf: &mut &[u8]) -> alloy_rlp::Result { Ok(Self { chain_id: Decodable::decode(buf)?, nonce: Decodable::decode(buf)?, diff --git a/crates/primitives/src/transaction/eip2930.rs b/crates/primitives/src/transaction/eip2930.rs index a888df62d84..514bde7e5d1 100644 --- a/crates/primitives/src/transaction/eip2930.rs +++ b/crates/primitives/src/transaction/eip2930.rs @@ -1,8 +1,8 @@ use super::access_list::AccessList; use crate::{keccak256, Bytes, ChainId, Signature, TransactionKind, TxType, H256}; +use alloy_rlp::{length_of_length, Decodable, Encodable, Header}; use bytes::BytesMut; use reth_codecs::{main_codec, Compact}; -use reth_rlp::{length_of_length, Decodable, DecodeError, Encodable, Header}; use std::mem; /// Transaction with an [`AccessList`] ([EIP-2930](https://eips.ethereum.org/EIPS/eip-2930)). @@ -80,7 +80,7 @@ impl TxEip2930 { /// - `value` /// - `data` (`input`) /// - `access_list` - pub(crate) fn decode_inner(buf: &mut &[u8]) -> Result { + pub(crate) fn decode_inner(buf: &mut &[u8]) -> alloy_rlp::Result { Ok(Self { chain_id: Decodable::decode(buf)?, nonce: Decodable::decode(buf)?, @@ -185,8 +185,8 @@ mod tests { transaction::{signature::Signature, TransactionKind}, Address, Bytes, Transaction, TransactionSigned, U256, }; + use alloy_rlp::{Decodable, Encodable}; use bytes::BytesMut; - use reth_rlp::{Decodable, Encodable}; #[test] fn test_decode_create() { diff --git a/crates/primitives/src/transaction/eip4844.rs b/crates/primitives/src/transaction/eip4844.rs index 058207998dc..26fa237c3e4 100644 --- a/crates/primitives/src/transaction/eip4844.rs +++ b/crates/primitives/src/transaction/eip4844.rs @@ -9,9 +9,9 @@ use crate::{ kzg_to_versioned_hash, Bytes, ChainId, Signature, Transaction, TransactionKind, TransactionSigned, TxHash, TxType, EIP4844_TX_TYPE_ID, H256, }; +use alloy_rlp::{length_of_length, Decodable, Encodable, Error as RlpError, Header}; use bytes::BytesMut; use reth_codecs::{main_codec, Compact}; -use reth_rlp::{length_of_length, Decodable, DecodeError, Encodable, Header}; use serde::{Deserialize, Serialize}; use std::{mem, ops::Deref}; @@ -190,7 +190,7 @@ impl TxEip4844 { /// - `access_list` /// - `max_fee_per_blob_gas` /// - `blob_versioned_hashes` - pub fn decode_inner(buf: &mut &[u8]) -> Result { + pub fn decode_inner(buf: &mut &[u8]) -> alloy_rlp::Result { Ok(Self { chain_id: Decodable::decode(buf)?, nonce: Decodable::decode(buf)?, @@ -517,11 +517,11 @@ impl BlobTransaction { /// /// Note: this should be used only when implementing other RLP decoding methods, and does not /// represent the full RLP decoding of the `PooledTransactionsElement` type. - pub(crate) fn decode_inner(data: &mut &[u8]) -> Result { + pub(crate) fn decode_inner(data: &mut &[u8]) -> alloy_rlp::Result { // decode the _first_ list header for the rest of the transaction let header = Header::decode(data)?; if !header.list { - return Err(DecodeError::Custom("PooledTransactions blob tx must be encoded as a list")) + return Err(RlpError::Custom("PooledTransactions blob tx must be encoded as a list")) } // Now we need to decode the inner 4844 transaction and its signature: @@ -529,7 +529,7 @@ impl BlobTransaction { // `[chain_id, nonce, max_priority_fee_per_gas, ..., y_parity, r, s]` let header = Header::decode(data)?; if !header.list { - return Err(DecodeError::Custom( + return Err(RlpError::Custom( "PooledTransactions inner blob tx must be encoded as a list", )) } @@ -569,6 +569,7 @@ impl BlobTransaction { /// This represents a set of blobs, and its corresponding commitments and proofs. #[derive(Clone, Debug, PartialEq, Eq, Default, Serialize, Deserialize)] +#[repr(C)] pub struct BlobTransactionSidecar { /// The blob data. pub blobs: Vec, @@ -586,10 +587,7 @@ impl BlobTransactionSidecar { /// - `commitments` /// - `proofs` pub(crate) fn encode_inner(&self, out: &mut dyn bytes::BufMut) { - // Encode the blobs, commitments, and proofs - self.blobs.encode(out); - self.commitments.encode(out); - self.proofs.encode(out); + BlobTransactionSidecarRlp::wrap_ref(self).encode(out); } /// Outputs the RLP length of the [BlobTransactionSidecar] fields, without a RLP header. @@ -603,12 +601,8 @@ impl BlobTransactionSidecar { /// - `blobs` /// - `commitments` /// - `proofs` - pub(crate) fn decode_inner(buf: &mut &[u8]) -> Result { - Ok(Self { - blobs: Decodable::decode(buf)?, - commitments: Decodable::decode(buf)?, - proofs: Decodable::decode(buf)?, - }) + pub(crate) fn decode_inner(buf: &mut &[u8]) -> alloy_rlp::Result { + Ok(BlobTransactionSidecarRlp::decode(buf)?.unwrap()) } /// Calculates a size heuristic for the in-memory size of the [BlobTransactionSidecar]. @@ -619,3 +613,41 @@ impl BlobTransactionSidecar { self.proofs.len() * BYTES_PER_PROOF // proofs } } + +// Wrapper for c-kzg rlp +#[repr(C)] +struct BlobTransactionSidecarRlp { + blobs: Vec<[u8; c_kzg::BYTES_PER_BLOB]>, + commitments: Vec<[u8; 48]>, + proofs: Vec<[u8; 48]>, +} + +const _: [(); std::mem::size_of::()] = + [(); std::mem::size_of::()]; + +impl BlobTransactionSidecarRlp { + fn wrap_ref(other: &BlobTransactionSidecar) -> &Self { + // SAFETY: Same repr and size + unsafe { &*(other as *const BlobTransactionSidecar).cast::() } + } + + fn unwrap(self) -> BlobTransactionSidecar { + // SAFETY: Same repr and size + unsafe { std::mem::transmute(self) } + } + + fn encode(&self, out: &mut dyn bytes::BufMut) { + // Encode the blobs, commitments, and proofs + self.blobs.encode(out); + self.commitments.encode(out); + self.proofs.encode(out); + } + + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { + Ok(Self { + blobs: Decodable::decode(buf)?, + commitments: Decodable::decode(buf)?, + proofs: Decodable::decode(buf)?, + }) + } +} diff --git a/crates/primitives/src/transaction/legacy.rs b/crates/primitives/src/transaction/legacy.rs index ec61490a54c..6039695fafa 100644 --- a/crates/primitives/src/transaction/legacy.rs +++ b/crates/primitives/src/transaction/legacy.rs @@ -1,7 +1,7 @@ use crate::{keccak256, Bytes, ChainId, Signature, TransactionKind, TxType, H256}; +use alloy_rlp::{length_of_length, Encodable, Header}; use bytes::BytesMut; use reth_codecs::{main_codec, Compact}; -use reth_rlp::{length_of_length, Encodable, Header}; use std::mem; /// Legacy transaction. diff --git a/crates/primitives/src/transaction/mod.rs b/crates/primitives/src/transaction/mod.rs index 0843014f7bd..f1c2f5b34a8 100644 --- a/crates/primitives/src/transaction/mod.rs +++ b/crates/primitives/src/transaction/mod.rs @@ -2,12 +2,14 @@ use crate::{ compression::{TRANSACTION_COMPRESSOR, TRANSACTION_DECOMPRESSOR}, keccak256, Address, Bytes, TxHash, H256, }; +use alloy_rlp::{ + Decodable, Encodable, Error as RlpError, Header, EMPTY_LIST_CODE, EMPTY_STRING_CODE, +}; use bytes::{Buf, BytesMut}; use derive_more::{AsRef, Deref}; use once_cell::sync::Lazy; use rayon::prelude::{IntoParallelIterator, ParallelIterator}; use reth_codecs::{add_arbitrary_tests, derive_arbitrary, Compact}; -use reth_rlp::{Decodable, DecodeError, Encodable, Header, EMPTY_LIST_CODE, EMPTY_STRING_CODE}; use serde::{Deserialize, Serialize}; use std::mem; @@ -595,7 +597,7 @@ impl Compact for TransactionKind { } impl Encodable for TransactionKind { - fn encode(&self, out: &mut dyn reth_rlp::BufMut) { + fn encode(&self, out: &mut dyn alloy_rlp::BufMut) { match self { TransactionKind::Call(to) => to.encode(out), TransactionKind::Create => out.put_u8(EMPTY_STRING_CODE), @@ -610,7 +612,7 @@ impl Encodable for TransactionKind { } impl Decodable for TransactionKind { - fn decode(buf: &mut &[u8]) -> Result { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { if let Some(&first) = buf.first() { if first == EMPTY_STRING_CODE { buf.advance(1); @@ -620,7 +622,7 @@ impl Decodable for TransactionKind { Ok(TransactionKind::Call(addr)) } } else { - Err(DecodeError::InputTooShort) + Err(RlpError::InputTooShort) } } } @@ -903,7 +905,7 @@ impl TransactionSigned { // so decoding methods do not need to manually advance the buffer pub(crate) fn decode_rlp_legacy_transaction_tuple( data: &mut &[u8], - ) -> Result<(TxLegacy, TxHash, Signature), DecodeError> { + ) -> alloy_rlp::Result<(TxLegacy, TxHash, Signature)> { // keep this around, so we can use it to calculate the hash let original_encoding = *data; @@ -931,9 +933,7 @@ impl TransactionSigned { /// This expects `rlp(legacy_tx)` // TODO: make buf advancement semantics consistent with `decode_enveloped_typed_transaction`, // so decoding methods do not need to manually advance the buffer - pub fn decode_rlp_legacy_transaction( - data: &mut &[u8], - ) -> Result { + pub fn decode_rlp_legacy_transaction(data: &mut &[u8]) -> alloy_rlp::Result { let (transaction, hash, signature) = TransactionSigned::decode_rlp_legacy_transaction_tuple(data)?; let signed = @@ -946,17 +946,17 @@ impl TransactionSigned { /// CAUTION: this expects that `data` is `[id, rlp(tx)]` pub fn decode_enveloped_typed_transaction( data: &mut &[u8], - ) -> Result { + ) -> alloy_rlp::Result { // keep this around so we can use it to calculate the hash let original_encoding = *data; - let tx_type = *data.first().ok_or(DecodeError::InputTooShort)?; + let tx_type = *data.first().ok_or(RlpError::InputTooShort)?; data.advance(1); // decode the list header for the rest of the transaction let header = Header::decode(data)?; if !header.list { - return Err(DecodeError::Custom("typed tx fields must be encoded as a list")) + return Err(RlpError::Custom("typed tx fields must be encoded as a list")) } // length of tx encoding = tx type byte (size = 1) + length of header + payload length @@ -967,7 +967,7 @@ impl TransactionSigned { 1 => Transaction::Eip2930(TxEip2930::decode_inner(data)?), 2 => Transaction::Eip1559(TxEip1559::decode_inner(data)?), 3 => Transaction::Eip4844(TxEip4844::decode_inner(data)?), - _ => return Err(DecodeError::Custom("unsupported typed transaction type")), + _ => return Err(RlpError::Custom("unsupported typed transaction type")), }; let signature = Signature::decode(data)?; @@ -983,11 +983,11 @@ impl TransactionSigned { /// For legacy transactions, the format is encoded as: `rlp(tx)` /// For EIP-2718 typed transaction, the format is encoded as the type of the transaction /// followed by the rlp of the transaction: `type` + `rlp(tx)` - pub fn decode_enveloped(tx: Bytes) -> Result { + pub fn decode_enveloped(tx: Bytes) -> alloy_rlp::Result { let mut data = tx.as_ref(); if data.is_empty() { - return Err(DecodeError::InputTooShort) + return Err(RlpError::InputTooShort) } // Check if the tx is a list @@ -1021,7 +1021,7 @@ impl Encodable for TransactionSigned { /// /// CAUTION: this expects that the given buf contains rlp impl Decodable for TransactionSigned { - fn decode(buf: &mut &[u8]) -> Result { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { // decode header let mut original_encoding = *buf; let header = Header::decode(buf)?; @@ -1130,11 +1130,11 @@ impl Encodable for TransactionSignedEcRecovered { } impl Decodable for TransactionSignedEcRecovered { - fn decode(buf: &mut &[u8]) -> Result { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { let signed_transaction = TransactionSigned::decode(buf)?; let signer = signed_transaction .recover_signer() - .ok_or(DecodeError::Custom("Unable to recover decoded transaction signer."))?; + .ok_or(RlpError::Custom("Unable to recover decoded transaction signer."))?; Ok(TransactionSignedEcRecovered { signer, signed_transaction }) } } @@ -1193,8 +1193,8 @@ mod tests { Address, Bytes, Transaction, TransactionSigned, TransactionSignedEcRecovered, H256, U256, }; use alloy_primitives::{b256, bytes}; + use alloy_rlp::{Decodable, Encodable, Error as RlpError}; use bytes::BytesMut; - use reth_rlp::{Decodable, DecodeError, Encodable}; use secp256k1::{KeyPair, Secp256k1}; use std::str::FromStr; @@ -1202,7 +1202,7 @@ mod tests { fn test_decode_empty_typed_tx() { let input = [0x80u8]; let res = TransactionSigned::decode(&mut &input[..]).unwrap_err(); - assert_eq!(DecodeError::InputTooShort, res); + assert_eq!(RlpError::InputTooShort, res); } #[test] diff --git a/crates/primitives/src/transaction/pooled.rs b/crates/primitives/src/transaction/pooled.rs index 8c5df265750..2cd354662a9 100644 --- a/crates/primitives/src/transaction/pooled.rs +++ b/crates/primitives/src/transaction/pooled.rs @@ -4,9 +4,9 @@ use crate::{ Address, BlobTransaction, Bytes, Signature, Transaction, TransactionSigned, TransactionSignedEcRecovered, TxEip1559, TxEip2930, TxHash, TxLegacy, EIP4844_TX_TYPE_ID, H256, }; +use alloy_rlp::{Decodable, Encodable, Error as RlpError, Header, EMPTY_LIST_CODE}; use bytes::Buf; use derive_more::{AsRef, Deref}; -use reth_rlp::{Decodable, DecodeError, Encodable, Header, EMPTY_LIST_CODE}; use serde::{Deserialize, Serialize}; /// A response to `GetPooledTransactions`. This can include either a blob transaction, or a @@ -115,11 +115,11 @@ impl PooledTransactionsElement { /// followed by the rlp of the transaction: `type` + `rlp(tx)` /// /// For encoded EIP-4844 transactions, the blob sidecar _must_ be included. - pub fn decode_enveloped(tx: Bytes) -> Result { + pub fn decode_enveloped(tx: Bytes) -> alloy_rlp::Result { let mut data = tx.as_ref(); if data.is_empty() { - return Err(DecodeError::InputTooShort) + return Err(RlpError::InputTooShort) } // Check if the tx is a list - tx types are less than EMPTY_LIST_CODE (0xc0) @@ -131,7 +131,7 @@ impl PooledTransactionsElement { Ok(Self::Legacy { transaction, signature, hash }) } else { // decode the type byte, only decode BlobTransaction if it is a 4844 transaction - let tx_type = *data.first().ok_or(DecodeError::InputTooShort)?; + let tx_type = *data.first().ok_or(RlpError::InputTooShort)?; if tx_type == EIP4844_TX_TYPE_ID { // Recall that the blob transaction response `TranactionPayload` is encoded like @@ -158,10 +158,10 @@ impl PooledTransactionsElement { // because we checked the tx type, we can be sure that the transaction is not a // blob transaction or legacy match typed_tx.transaction { - Transaction::Legacy(_) => Err(DecodeError::Custom( + Transaction::Legacy(_) => Err(RlpError::Custom( "legacy transactions should not be a result of EIP-2718 decoding", )), - Transaction::Eip4844(_) => Err(DecodeError::Custom( + Transaction::Eip4844(_) => Err(RlpError::Custom( "EIP-4844 transactions can only be decoded with transaction type 0x03", )), Transaction::Eip2930(tx) => Ok(PooledTransactionsElement::Eip2930 { @@ -256,7 +256,7 @@ impl Decodable for PooledTransactionsElement { /// Decodes an enveloped post EIP-4844 [PooledTransactionsElement]. /// /// CAUTION: this expects that `buf` is `[id, rlp(tx)]` - fn decode(buf: &mut &[u8]) -> Result { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { // From the EIP-4844 spec: // Blob transactions have two network representations. During transaction gossip responses // (`PooledTransactions`), the EIP-2718 `TransactionPayload` of the blob transaction is @@ -269,7 +269,7 @@ impl Decodable for PooledTransactionsElement { // // First, we check whether or not the transaction is a legacy transaction. if buf.is_empty() { - return Err(DecodeError::InputTooShort) + return Err(RlpError::InputTooShort) } // keep this around for buffer advancement post-legacy decoding @@ -292,7 +292,7 @@ impl Decodable for PooledTransactionsElement { Ok(Self::Legacy { transaction, signature, hash }) } else { // decode the type byte, only decode BlobTransaction if it is a 4844 transaction - let tx_type = *buf.first().ok_or(DecodeError::InputTooShort)?; + let tx_type = *buf.first().ok_or(RlpError::InputTooShort)?; if tx_type == EIP4844_TX_TYPE_ID { // Recall that the blob transaction response `TranactionPayload` is encoded like @@ -319,10 +319,10 @@ impl Decodable for PooledTransactionsElement { // because we checked the tx type, we can be sure that the transaction is not a // blob transaction or legacy match typed_tx.transaction { - Transaction::Legacy(_) => Err(DecodeError::Custom( + Transaction::Legacy(_) => Err(RlpError::Custom( "legacy transactions should not be a result of EIP-2718 decoding", )), - Transaction::Eip4844(_) => Err(DecodeError::Custom( + Transaction::Eip4844(_) => Err(RlpError::Custom( "EIP-4844 transactions can only be decoded with transaction type 0x03", )), Transaction::Eip2930(tx) => Ok(PooledTransactionsElement::Eip2930 { diff --git a/crates/primitives/src/transaction/signature.rs b/crates/primitives/src/transaction/signature.rs index 0c8f2e883d8..96c122ad303 100644 --- a/crates/primitives/src/transaction/signature.rs +++ b/crates/primitives/src/transaction/signature.rs @@ -1,8 +1,8 @@ use crate::{transaction::util::secp256k1, Address, H256, U256}; use alloy_primitives::Bytes; +use alloy_rlp::{Decodable, Encodable, Error as RlpError}; use bytes::Buf; use reth_codecs::{derive_arbitrary, Compact}; -use reth_rlp::{Decodable, DecodeError, Encodable}; use serde::{Deserialize, Serialize}; /// r, s: Values corresponding to the signature of the @@ -51,7 +51,7 @@ impl Signature { /// Encodes the `v` value using the legacy scheme with EIP-155 support depends on chain_id. pub(crate) fn encode_with_eip155_chain_id( &self, - out: &mut dyn reth_rlp::BufMut, + out: &mut dyn alloy_rlp::BufMut, chain_id: Option, ) { self.v(chain_id).encode(out); @@ -74,7 +74,7 @@ impl Signature { /// This will return a chain ID if the `v` value is [EIP-155](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md) compatible. pub(crate) fn decode_with_eip155_chain_id( buf: &mut &[u8], - ) -> Result<(Self, Option), DecodeError> { + ) -> alloy_rlp::Result<(Self, Option)> { let v = u64::decode(buf)?; let r = Decodable::decode(buf)?; let s = Decodable::decode(buf)?; @@ -86,7 +86,7 @@ impl Signature { } else { // non-EIP-155 legacy scheme, v = 27 for even y-parity, v = 28 for odd y-parity if v != 27 && v != 28 { - return Err(DecodeError::Custom("invalid Ethereum signature (V is not 27 or 28)")) + return Err(RlpError::Custom("invalid Ethereum signature (V is not 27 or 28)")) } let odd_y_parity = v == 28; Ok((Signature { r, s, odd_y_parity }, None)) @@ -99,14 +99,14 @@ impl Signature { } /// Encode the `odd_y_parity`, `r`, `s` values without a RLP header. - pub fn encode(&self, out: &mut dyn reth_rlp::BufMut) { + pub fn encode(&self, out: &mut dyn alloy_rlp::BufMut) { self.odd_y_parity.encode(out); self.r.encode(out); self.s.encode(out); } /// Decodes the `odd_y_parity`, `r`, `s` values without a RLP header. - pub fn decode(buf: &mut &[u8]) -> Result { + pub fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { Ok(Signature { odd_y_parity: Decodable::decode(buf)?, r: Decodable::decode(buf)?, diff --git a/crates/primitives/src/trie/hash_builder/mod.rs b/crates/primitives/src/trie/hash_builder/mod.rs index dbd0c27805d..a16ca2b6ff5 100644 --- a/crates/primitives/src/trie/hash_builder/mod.rs +++ b/crates/primitives/src/trie/hash_builder/mod.rs @@ -439,7 +439,7 @@ mod tests { K: AsRef<[u8]> + Ord, { let hashed = iter - .map(|(k, v)| (keccak256(k.as_ref()), reth_rlp::encode_fixed_size(v).to_vec())) + .map(|(k, v)| (keccak256(k.as_ref()), alloy_rlp::encode_fixed_size(v).to_vec())) // Collect into a btree map to sort the data .collect::>(); @@ -590,7 +590,7 @@ mod tests { // Skip the 0th element given in this example they have a common prefix and will // collapse to a Branch node. use crate::bytes::BytesMut; - use reth_rlp::Encodable; + use alloy_rlp::Encodable; let leaf1 = LeafNode::new(&Nibbles::unpack(&raw_input[0].0[1..]), input[0].1); let leaf2 = LeafNode::new(&Nibbles::unpack(&raw_input[1].0[1..]), input[1].1); let mut branch: [&dyn Encodable; 17] = [b""; 17]; @@ -599,7 +599,7 @@ mod tests { branch[4] = &leaf1; branch[7] = &leaf2; let mut branch_node_rlp = BytesMut::new(); - reth_rlp::encode_list::(&branch, &mut branch_node_rlp); + alloy_rlp::encode_list::<_, dyn Encodable>(&branch, &mut branch_node_rlp); let branch_node_hash = keccak256(branch_node_rlp); let mut hb2 = HashBuilder::default(); diff --git a/crates/primitives/src/trie/nibbles.rs b/crates/primitives/src/trie/nibbles.rs index d26350e3953..f53c0ecc9a7 100644 --- a/crates/primitives/src/trie/nibbles.rs +++ b/crates/primitives/src/trie/nibbles.rs @@ -1,7 +1,7 @@ use crate::Bytes; +use alloy_rlp::RlpEncodableWrapper; use derive_more::{Deref, DerefMut, From, Index}; use reth_codecs::{main_codec, Compact}; -use reth_rlp::RlpEncodableWrapper; use serde::{Deserialize, Serialize}; /// The nibbles are the keys for the AccountsTrie and the subkeys for the StorageTrie. diff --git a/crates/primitives/src/trie/nodes/branch.rs b/crates/primitives/src/trie/nodes/branch.rs index cad3e94f50d..69ec1664c7e 100644 --- a/crates/primitives/src/trie/nodes/branch.rs +++ b/crates/primitives/src/trie/nodes/branch.rs @@ -1,8 +1,8 @@ use super::{super::TrieMask, rlp_node, CHILD_INDEX_RANGE}; use crate::H256; +use alloy_rlp::{BufMut, EMPTY_STRING_CODE}; use bytes::Buf; use reth_codecs::Compact; -use reth_rlp::{BufMut, EMPTY_STRING_CODE}; use serde::{Deserialize, Serialize}; /// A Branch node is only a pointer to the stack of nodes and is used to @@ -47,7 +47,7 @@ impl<'a> BranchNode<'a> { // Create the RLP header from the mask elements present. let mut i = first_child_idx; let header = CHILD_INDEX_RANGE.fold( - reth_rlp::Header { list: true, payload_length: 1 }, + alloy_rlp::Header { list: true, payload_length: 1 }, |mut header, digit| { if state_mask.is_bit_set(digit) { header.payload_length += self.stack[i].len(); diff --git a/crates/primitives/src/trie/nodes/extension.rs b/crates/primitives/src/trie/nodes/extension.rs index af53f6d480c..09fe529ecfc 100644 --- a/crates/primitives/src/trie/nodes/extension.rs +++ b/crates/primitives/src/trie/nodes/extension.rs @@ -1,5 +1,5 @@ use super::{super::Nibbles, rlp_node}; -use reth_rlp::{BufMut, Encodable}; +use alloy_rlp::{BufMut, Encodable}; /// An intermediate node that exists solely to compress the trie's paths. It contains a path segment /// (a shared prefix of keys) and a single child pointer. Essentially, an extension node can be @@ -30,7 +30,7 @@ impl<'a> ExtensionNode<'a> { impl Encodable for ExtensionNode<'_> { fn encode(&self, out: &mut dyn BufMut) { - let h = reth_rlp::Header { + let h = alloy_rlp::Header { list: true, payload_length: self.prefix.as_slice().length() + self.node.len(), }; diff --git a/crates/primitives/src/trie/nodes/leaf.rs b/crates/primitives/src/trie/nodes/leaf.rs index 4f518dc6026..9fb016e1505 100644 --- a/crates/primitives/src/trie/nodes/leaf.rs +++ b/crates/primitives/src/trie/nodes/leaf.rs @@ -1,5 +1,5 @@ use super::{super::Nibbles, rlp_node}; -use reth_rlp::{BufMut, Encodable}; +use alloy_rlp::{BufMut, Encodable}; /// A leaf node represents the endpoint or terminal node in the trie. In other words, a leaf node is /// where actual values are stored. @@ -33,7 +33,7 @@ impl<'a> LeafNode<'a> { // Handroll because `key` must be encoded as a slice impl Encodable for LeafNode<'_> { fn encode(&self, out: &mut dyn BufMut) { - #[derive(reth_rlp::RlpEncodable)] + #[derive(alloy_rlp::RlpEncodable)] struct S<'a> { encoded_path: &'a [u8], value: &'a [u8], diff --git a/crates/primitives/src/trie/nodes/mod.rs b/crates/primitives/src/trie/nodes/mod.rs index c4807444d83..04d96f9443e 100644 --- a/crates/primitives/src/trie/nodes/mod.rs +++ b/crates/primitives/src/trie/nodes/mod.rs @@ -1,5 +1,5 @@ use crate::{keccak256, H256}; -use reth_rlp::EMPTY_STRING_CODE; +use alloy_rlp::EMPTY_STRING_CODE; use std::ops::Range; mod branch; diff --git a/crates/primitives/src/withdrawal.rs b/crates/primitives/src/withdrawal.rs index 6df6d73ecb7..c99a51664c3 100644 --- a/crates/primitives/src/withdrawal.rs +++ b/crates/primitives/src/withdrawal.rs @@ -1,6 +1,6 @@ use crate::{constants::GWEI_TO_WEI, serde_helper::u64_hex, Address}; +use alloy_rlp::{RlpDecodable, RlpEncodable}; use reth_codecs::{main_codec, Compact}; -use reth_rlp::{RlpDecodable, RlpEncodable}; use std::mem; /// Withdrawal represents a validator withdrawal from the consensus layer. diff --git a/crates/rlp/Cargo.toml b/crates/rlp/Cargo.toml deleted file mode 100644 index 8a92f6388d6..00000000000 --- a/crates/rlp/Cargo.toml +++ /dev/null @@ -1,45 +0,0 @@ -[package] -name = "reth-rlp" -version.workspace = true -edition.workspace = true -rust-version.workspace = true -license = "Apache-2.0" -description = "Fast RLP serialization library" -homepage.workspace = true -repository.workspace = true - -[dependencies] -arrayvec = { version = "0.7", default-features = false } -auto_impl = "1" -bytes.workspace = true -ethnum = { version = "1", default-features = false, optional = true } -smol_str = { version = "0.2", default-features = false, optional = true } -ethereum-types = { version = "0.14", features = ["codec"], optional = true } -revm-primitives = { workspace = true, features = ["serde"] } -reth-rlp-derive = { path = "./rlp-derive", optional = true } - -# for eip-4844 -c-kzg = { workspace = true, optional = true } - -[dev-dependencies] -reth-rlp = { workspace = true, features = [ - "derive", - "std", - "ethnum", - "ethereum-types", - "smol_str", -] } -hex-literal.workspace = true -criterion = "0.5.0" -pprof = { version = "0.12", features = ["flamegraph", "frame-pointer", "criterion"] } - -[features] -default = ["kzg"] -alloc = [] -derive = ["reth-rlp-derive"] -std = ["alloc"] -kzg = ["c-kzg"] - -[[bench]] -name = "bench" -harness = false diff --git a/crates/rlp/LICENCE b/crates/rlp/LICENCE deleted file mode 100644 index 9c8f3ea0871..00000000000 --- a/crates/rlp/LICENCE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/crates/rlp/README.md b/crates/rlp/README.md deleted file mode 100644 index 0fda03ed21d..00000000000 --- a/crates/rlp/README.md +++ /dev/null @@ -1,4 +0,0 @@ -## RLP encoder/decoder - -Forked from an earlier Apache licenced version of the `fastrlp` crate, before it changed licence to GPL. -NOTE: The Rust fastrlp implementation is itself a port of the [Golang Apache licensed fastrlp](https://github.com/umbracle/fastrlp) \ No newline at end of file diff --git a/crates/rlp/benches/bench.rs b/crates/rlp/benches/bench.rs deleted file mode 100644 index e6969518314..00000000000 --- a/crates/rlp/benches/bench.rs +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2020 Parity Technologies -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! benchmarking for rlp - -use bytes::BytesMut; -use criterion::{criterion_group, criterion_main, Criterion}; -use ethnum::*; -use hex_literal::hex; -use pprof::criterion::{Output, PProfProfiler}; -use reth_rlp::*; - -fn bench_encode(c: &mut Criterion) { - c.bench_function("encode_u64", |b| { - b.iter(|| { - let mut out = BytesMut::new(); - 0x1023_4567_89ab_cdefu64.encode(&mut out); - }) - }); - c.bench_function("encode_u256", |b| { - b.iter(|| { - let mut out = BytesMut::new(); - let uint = U256::from_be_bytes(hex!( - "8090a0b0c0d0e0f00910203040506077000000000000000100000000000012f0" - )); - uint.encode(&mut out); - }) - }); - c.bench_function("encode_1000_u64", |b| { - b.iter(|| { - let mut out = BytesMut::new(); - reth_rlp::encode_list((0..1000u64).collect::>().as_slice(), &mut out); - }) - }); -} - -fn bench_decode(c: &mut Criterion) { - c.bench_function("decode_u64", |b| { - b.iter(|| { - let data = [0x88, 0x10, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef]; - let _ = u64::decode(&mut &data[..]).unwrap(); - }) - }); - c.bench_function("decode_u256", |b| { - b.iter(|| { - let data = [ - 0xa0, 0x80, 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0x09, 0x10, 0x20, 0x30, 0x40, - 0x50, 0x60, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x12, 0xf0, - ]; - let _ = U256::decode(&mut &data[..]).unwrap(); - }) - }); - c.bench_function("decode_1000_u64", |b| { - let input = (0..1000u64).collect::>(); - let mut data = BytesMut::new(); - reth_rlp::encode_list(input.as_slice(), &mut data); - b.iter(|| { - let _ = Vec::::decode(&mut &data[..]).unwrap(); - }); - }); -} - -criterion_group! { - name = benches; - config = Criterion::default().with_profiler(PProfProfiler::new(100, Output::Flamegraph(None))); - targets = bench_encode, bench_decode -} -criterion_main!(benches); diff --git a/crates/rlp/rlp-derive/Cargo.toml b/crates/rlp/rlp-derive/Cargo.toml deleted file mode 100644 index 72760af83d9..00000000000 --- a/crates/rlp/rlp-derive/Cargo.toml +++ /dev/null @@ -1,17 +0,0 @@ -[package] -name = "reth-rlp-derive" -version.workspace = true -license = "Apache-2.0" -edition.workspace = true -rust-version.workspace = true -description = "Procedural macros for reth-rlp" -homepage.workspace = true -repository.workspace = true - -[lib] -proc-macro = true - -[dependencies] -syn = "2" -quote.workspace = true -proc-macro2.workspace = true diff --git a/crates/rlp/rlp-derive/LICENCE b/crates/rlp/rlp-derive/LICENCE deleted file mode 100644 index 9c8f3ea0871..00000000000 --- a/crates/rlp/rlp-derive/LICENCE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "{}" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright {yyyy} {name of copyright owner} - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/crates/rlp/rlp-derive/README.md b/crates/rlp/rlp-derive/README.md deleted file mode 100644 index a105019ab65..00000000000 --- a/crates/rlp/rlp-derive/README.md +++ /dev/null @@ -1,4 +0,0 @@ -## RLP derive crate - -Forked from an earlier Apache licenced version of the `fastrlp-derive` crate, before it changed licence to GPL. -NOTE: The Rust fastrlp implementation is itself a port of the [Golang Apache licensed fastrlp](https://github.com/umbracle/fastrlp) diff --git a/crates/rlp/rlp-derive/src/de.rs b/crates/rlp/rlp-derive/src/de.rs deleted file mode 100644 index aab545fd86d..00000000000 --- a/crates/rlp/rlp-derive/src/de.rs +++ /dev/null @@ -1,123 +0,0 @@ -use proc_macro2::TokenStream; -use quote::quote; -use syn::{Error, Result}; - -use crate::utils::{attributes_include, field_ident, is_optional, parse_struct, EMPTY_STRING_CODE}; - -pub(crate) fn impl_decodable(ast: &syn::DeriveInput) -> Result { - let body = parse_struct(ast, "RlpDecodable")?; - - let fields = body.fields.iter().enumerate(); - - let supports_trailing_opt = attributes_include(&ast.attrs, "trailing"); - - let mut encountered_opt_item = false; - let mut stmts = Vec::with_capacity(body.fields.len()); - for (i, field) in fields { - let is_opt = is_optional(field); - if is_opt { - if !supports_trailing_opt { - return Err(Error::new_spanned(field, "Optional fields are disabled. Add `#[rlp(trailing)]` attribute to the struct in order to enable")); - } - encountered_opt_item = true; - } else if encountered_opt_item && !attributes_include(&field.attrs, "default") { - return Err(Error::new_spanned( - field, - "All subsequent fields must be either optional or default.", - )) - } - - stmts.push(decodable_field(i, field, is_opt)); - } - - let name = &ast.ident; - let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl(); - - let impl_block = quote! { - impl #impl_generics reth_rlp::Decodable for #name #ty_generics #where_clause { - fn decode(mut buf: &mut &[u8]) -> Result { - let b = &mut &**buf; - let rlp_head = reth_rlp::Header::decode(b)?; - - if !rlp_head.list { - return Err(reth_rlp::DecodeError::UnexpectedString); - } - - let started_len = b.len(); - let this = Self { - #(#stmts)* - }; - - let consumed = started_len - b.len(); - if consumed != rlp_head.payload_length { - return Err(reth_rlp::DecodeError::ListLengthMismatch { - expected: rlp_head.payload_length, - got: consumed, - }); - } - - *buf = *b; - - Ok(this) - } - } - }; - - Ok(quote! { - const _: () = { - extern crate reth_rlp; - #impl_block - }; - }) -} - -pub(crate) fn impl_decodable_wrapper(ast: &syn::DeriveInput) -> Result { - let body = parse_struct(ast, "RlpDecodableWrapper")?; - - assert_eq!( - body.fields.iter().count(), - 1, - "#[derive(RlpDecodableWrapper)] is only defined for structs with one field." - ); - - let name = &ast.ident; - let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl(); - - let impl_block = quote! { - impl #impl_generics reth_rlp::Decodable for #name #ty_generics #where_clause { - fn decode(buf: &mut &[u8]) -> Result { - Ok(Self(reth_rlp::Decodable::decode(buf)?)) - } - } - }; - - Ok(quote! { - const _: () = { - extern crate reth_rlp; - #impl_block - }; - }) -} - -fn decodable_field(index: usize, field: &syn::Field, is_opt: bool) -> TokenStream { - let ident = field_ident(index, field); - - if attributes_include(&field.attrs, "default") { - quote! { #ident: Default::default(), } - } else if is_opt { - quote! { - #ident: if started_len - b.len() < rlp_head.payload_length { - if b.first().map(|b| *b == #EMPTY_STRING_CODE).unwrap_or_default() { - bytes::Buf::advance(b, 1); - None - } else { - Some(reth_rlp::Decodable::decode(b)?) - } - } else { - None - }, - } - } else { - quote! { #ident: reth_rlp::Decodable::decode(b)?, } - } -} diff --git a/crates/rlp/rlp-derive/src/en.rs b/crates/rlp/rlp-derive/src/en.rs deleted file mode 100644 index dda14741f0b..00000000000 --- a/crates/rlp/rlp-derive/src/en.rs +++ /dev/null @@ -1,209 +0,0 @@ -use std::iter::Peekable; - -use proc_macro2::TokenStream; -use quote::quote; -use syn::{Error, Result}; - -use crate::utils::{attributes_include, field_ident, is_optional, parse_struct, EMPTY_STRING_CODE}; - -pub(crate) fn impl_encodable(ast: &syn::DeriveInput) -> Result { - let body = parse_struct(ast, "RlpEncodable")?; - - let mut fields = body - .fields - .iter() - .enumerate() - .filter(|(_, field)| !attributes_include(&field.attrs, "skip")) - .peekable(); - - let supports_trailing_opt = attributes_include(&ast.attrs, "trailing"); - - let mut encountered_opt_item = false; - let mut length_stmts = Vec::with_capacity(body.fields.len()); - let mut stmts = Vec::with_capacity(body.fields.len()); - - while let Some((i, field)) = fields.next() { - let is_opt = is_optional(field); - if is_opt { - if !supports_trailing_opt { - return Err(Error::new_spanned(field, "Optional fields are disabled. Add `#[rlp(trailing)]` attribute to the struct in order to enable")); - } - encountered_opt_item = true; - } else if encountered_opt_item { - return Err(Error::new_spanned(field, "All subsequent fields must be optional.")) - } - - length_stmts.push(encodable_length(i, field, is_opt, fields.clone())); - stmts.push(encodable_field(i, field, is_opt, fields.clone())); - } - - let name = &ast.ident; - let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl(); - - let impl_block = quote! { - trait E { - fn rlp_header(&self) -> reth_rlp::Header; - } - - impl #impl_generics E for #name #ty_generics #where_clause { - fn rlp_header(&self) -> reth_rlp::Header { - let mut rlp_head = reth_rlp::Header { list: true, payload_length: 0 }; - #(#length_stmts)* - rlp_head - } - } - - impl #impl_generics reth_rlp::Encodable for #name #ty_generics #where_clause { - fn length(&self) -> usize { - let rlp_head = E::rlp_header(self); - return reth_rlp::length_of_length(rlp_head.payload_length) + rlp_head.payload_length; - } - fn encode(&self, out: &mut dyn reth_rlp::BufMut) { - E::rlp_header(self).encode(out); - #(#stmts)* - } - } - }; - - Ok(quote! { - const _: () = { - extern crate reth_rlp; - #impl_block - }; - }) -} - -pub(crate) fn impl_encodable_wrapper(ast: &syn::DeriveInput) -> Result { - let body = parse_struct(ast, "RlpEncodableWrapper")?; - - let ident = { - let fields: Vec<_> = body.fields.iter().collect(); - if fields.len() == 1 { - let field = fields.first().expect("fields.len() == 1; qed"); - field_ident(0, field) - } else { - panic!("#[derive(RlpEncodableWrapper)] is only defined for structs with one field.") - } - }; - - let name = &ast.ident; - let (impl_generics, ty_generics, where_clause) = ast.generics.split_for_impl(); - - let impl_block = quote! { - impl #impl_generics reth_rlp::Encodable for #name #ty_generics #where_clause { - fn length(&self) -> usize { - self.#ident.length() - } - fn encode(&self, out: &mut dyn reth_rlp::BufMut) { - self.#ident.encode(out) - } - } - }; - - Ok(quote! { - const _: () = { - extern crate reth_rlp; - #impl_block - }; - }) -} - -pub(crate) fn impl_max_encoded_len(ast: &syn::DeriveInput) -> Result { - let body = parse_struct(ast, "RlpMaxEncodedLen")?; - - let stmts: Vec<_> = body - .fields - .iter() - .enumerate() - .filter(|(_, field)| !attributes_include(&field.attrs, "skip")) - .map(|(index, field)| encodable_max_length(index, field)) - .collect(); - let name = &ast.ident; - - let impl_block = quote! { - unsafe impl reth_rlp::MaxEncodedLen<{ reth_rlp::const_add(reth_rlp::length_of_length(#(#stmts)*), #(#stmts)*) }> for #name {} - unsafe impl reth_rlp::MaxEncodedLenAssoc for #name { - const LEN: usize = { reth_rlp::const_add(reth_rlp::length_of_length(#(#stmts)*), { #(#stmts)* }) }; - } - }; - - Ok(quote! { - const _: () = { - extern crate reth_rlp; - #impl_block - }; - }) -} - -fn encodable_length<'a>( - index: usize, - field: &syn::Field, - is_opt: bool, - mut remaining: Peekable>, -) -> TokenStream { - let ident = field_ident(index, field); - - if is_opt { - let default = if remaining.peek().is_some() { - let condition = remaining_opt_fields_some_condition(remaining); - quote! { #condition as usize } - } else { - quote! { 0 } - }; - - quote! { rlp_head.payload_length += &self.#ident.as_ref().map(|val| reth_rlp::Encodable::length(val)).unwrap_or(#default); } - } else { - quote! { rlp_head.payload_length += reth_rlp::Encodable::length(&self.#ident); } - } -} - -fn encodable_max_length(index: usize, field: &syn::Field) -> TokenStream { - let fieldtype = &field.ty; - - if index == 0 { - quote! { <#fieldtype as reth_rlp::MaxEncodedLenAssoc>::LEN } - } else { - quote! { + <#fieldtype as reth_rlp::MaxEncodedLenAssoc>::LEN } - } -} - -fn encodable_field<'a>( - index: usize, - field: &syn::Field, - is_opt: bool, - mut remaining: Peekable>, -) -> TokenStream { - let ident = field_ident(index, field); - - if is_opt { - let if_some_encode = quote! { - if let Some(val) = self.#ident.as_ref() { - reth_rlp::Encodable::encode(val, out) - } - }; - - if remaining.peek().is_some() { - let condition = remaining_opt_fields_some_condition(remaining); - quote! { - #if_some_encode - else if #condition { - out.put_u8(#EMPTY_STRING_CODE); - } - } - } else { - quote! { #if_some_encode } - } - } else { - quote! { reth_rlp::Encodable::encode(&self.#ident, out); } - } -} - -fn remaining_opt_fields_some_condition<'a>( - remaining: impl Iterator, -) -> TokenStream { - let conditions = remaining.map(|(index, field)| { - let ident = field_ident(index, field); - quote! { self.#ident.is_some() } - }); - quote! { #(#conditions) ||* } -} diff --git a/crates/rlp/rlp-derive/src/lib.rs b/crates/rlp/rlp-derive/src/lib.rs deleted file mode 100644 index 02d9bc4449c..00000000000 --- a/crates/rlp/rlp-derive/src/lib.rs +++ /dev/null @@ -1,83 +0,0 @@ -#![cfg_attr(docsrs, feature(doc_cfg))] -#![doc( - html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", - html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxzy/reth/issues/" -)] -#![warn(missing_docs, unreachable_pub)] -#![deny(unused_must_use, unused_crate_dependencies)] -#![doc(test( - no_crate_inject, - attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables)) -))] - -//! Derive macro for `#[derive(RlpEncodable, RlpDecodable)]`. -//! -//! For example of usage see `./tests/rlp.rs`. -//! -//! This library also supports up to 1 `#[rlp(default)]` in a struct, -//! which is similar to [`#[serde(default)]`](https://serde.rs/field-attrs.html#default) -//! with the caveat that we use the `Default` value if -//! the field deserialization fails, as we don't serialize field -//! names and there is no way to tell if it is present or not. - -extern crate proc_macro; - -mod de; -mod en; -mod utils; - -use de::*; -use en::*; -use proc_macro::TokenStream; - -/// Derives `Encodable` for the type which encodes the all fields as list: `` -#[proc_macro_derive(RlpEncodable, attributes(rlp))] -pub fn encodable(input: TokenStream) -> TokenStream { - syn::parse(input) - .and_then(|ast| impl_encodable(&ast)) - .unwrap_or_else(|err| err.to_compile_error()) - .into() -} - -/// Derives `Encodable` for the type which encodes the fields as-is, without a header: `` -#[proc_macro_derive(RlpEncodableWrapper, attributes(rlp))] -pub fn encodable_wrapper(input: TokenStream) -> TokenStream { - syn::parse(input) - .and_then(|ast| impl_encodable_wrapper(&ast)) - .unwrap_or_else(|err| err.to_compile_error()) - .into() -} - -/// Derives `MaxEncodedLen` for types of constant size. -#[proc_macro_derive(RlpMaxEncodedLen, attributes(rlp))] -pub fn max_encoded_len(input: TokenStream) -> TokenStream { - syn::parse(input) - .and_then(|ast| impl_max_encoded_len(&ast)) - .unwrap_or_else(|err| err.to_compile_error()) - .into() -} - -/// Derives `Decodable` for the type whose implementation expects an rlp-list input: `` -/// -/// This is the inverse of `RlpEncodable`. -#[proc_macro_derive(RlpDecodable, attributes(rlp))] -pub fn decodable(input: TokenStream) -> TokenStream { - syn::parse(input) - .and_then(|ast| impl_decodable(&ast)) - .unwrap_or_else(|err| err.to_compile_error()) - .into() -} - -/// Derives `Decodable` for the type whose implementation expects only the individual fields -/// encoded: `` -/// -/// This is the inverse of `RlpEncodableWrapper`. -#[proc_macro_derive(RlpDecodableWrapper, attributes(rlp))] -pub fn decodable_wrapper(input: TokenStream) -> TokenStream { - syn::parse(input) - .and_then(|ast| impl_decodable_wrapper(&ast)) - .unwrap_or_else(|err| err.to_compile_error()) - .into() -} diff --git a/crates/rlp/rlp-derive/src/utils.rs b/crates/rlp/rlp-derive/src/utils.rs deleted file mode 100644 index f4d4c87679c..00000000000 --- a/crates/rlp/rlp-derive/src/utils.rs +++ /dev/null @@ -1,57 +0,0 @@ -use proc_macro2::TokenStream; -use quote::quote; -use syn::{Attribute, DataStruct, Error, Field, Meta, Result, Type, TypePath}; - -pub(crate) const EMPTY_STRING_CODE: u8 = 0x80; - -pub(crate) fn parse_struct<'a>( - ast: &'a syn::DeriveInput, - derive_attr: &str, -) -> Result<&'a DataStruct> { - if let syn::Data::Struct(s) = &ast.data { - Ok(s) - } else { - Err(Error::new_spanned( - ast, - format!("#[derive({derive_attr})] is only defined for structs."), - )) - } -} - -pub(crate) fn attributes_include(attrs: &[Attribute], attr_name: &str) -> bool { - for attr in attrs.iter() { - if attr.path().is_ident("rlp") { - if let Meta::List(meta) = &attr.meta { - let mut is_attr = false; - let _ = meta.parse_nested_meta(|meta| { - is_attr = meta.path.is_ident(attr_name); - Ok(()) - }); - if is_attr { - return true - } - } - } - } - false -} - -pub(crate) fn is_optional(field: &Field) -> bool { - if let Type::Path(TypePath { qself, path }) = &field.ty { - qself.is_none() && - path.leading_colon.is_none() && - path.segments.len() == 1 && - path.segments.first().unwrap().ident == "Option" - } else { - false - } -} - -pub(crate) fn field_ident(index: usize, field: &syn::Field) -> TokenStream { - if let Some(ident) = &field.ident { - quote! { #ident } - } else { - let index = syn::Index::from(index); - quote! { #index } - } -} diff --git a/crates/rlp/src/decode.rs b/crates/rlp/src/decode.rs deleted file mode 100644 index 9243bebe124..00000000000 --- a/crates/rlp/src/decode.rs +++ /dev/null @@ -1,688 +0,0 @@ -use crate::types::Header; -use bytes::{Buf, Bytes, BytesMut}; - -pub trait Decodable: Sized { - fn decode(buf: &mut &[u8]) -> Result; -} - -#[cfg(feature = "alloc")] -mod alloc_impl { - use super::*; - - impl Decodable for ::alloc::boxed::Box - where - T: Decodable + Sized, - { - fn decode(buf: &mut &[u8]) -> Result { - T::decode(buf).map(::alloc::boxed::Box::new) - } - } - - impl Decodable for ::alloc::sync::Arc - where - T: Decodable + Sized, - { - fn decode(buf: &mut &[u8]) -> Result { - T::decode(buf).map(::alloc::sync::Arc::new) - } - } - - impl Decodable for ::alloc::string::String { - fn decode(from: &mut &[u8]) -> Result { - let h = Header::decode(from)?; - if h.list { - return Err(DecodeError::UnexpectedList) - } - let mut to = ::alloc::vec::Vec::with_capacity(h.payload_length); - to.extend_from_slice(&from[..h.payload_length]); - from.advance(h.payload_length); - - Self::from_utf8(to).map_err(|_| DecodeError::Custom("invalid string")) - } - } -} - -#[derive(Clone, Copy, Debug, Eq, PartialEq)] -pub enum DecodeError { - Overflow, - LeadingZero, - InputTooShort, - NonCanonicalSingleByte, - NonCanonicalSize, - UnexpectedLength, - UnexpectedString, - UnexpectedList, - ListLengthMismatch { expected: usize, got: usize }, - Custom(&'static str), -} - -#[cfg(feature = "std")] -impl std::error::Error for DecodeError {} - -impl core::fmt::Display for DecodeError { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - match self { - DecodeError::Overflow => write!(f, "overflow"), - DecodeError::LeadingZero => write!(f, "leading zero"), - DecodeError::InputTooShort => write!(f, "input too short"), - DecodeError::NonCanonicalSingleByte => write!(f, "non-canonical single byte"), - DecodeError::NonCanonicalSize => write!(f, "non-canonical size"), - DecodeError::UnexpectedLength => write!(f, "unexpected length"), - DecodeError::UnexpectedString => write!(f, "unexpected string"), - DecodeError::UnexpectedList => write!(f, "unexpected list"), - DecodeError::ListLengthMismatch { expected, got } => { - write!(f, "list length mismatch: expected {expected}, got {got}") - } - DecodeError::Custom(err) => write!(f, "{err}"), - } - } -} - -impl Header { - /// Returns the decoded header. - /// - /// Returns an error if the given `buf`'s len is less than the expected payload. - pub fn decode(buf: &mut &[u8]) -> Result { - if !buf.has_remaining() { - return Err(DecodeError::InputTooShort) - } - - let b = buf[0]; - let h: Self = { - if b < 0x80 { - Self { list: false, payload_length: 1 } - } else if b < 0xB8 { - buf.advance(1); - let h = Self { list: false, payload_length: b as usize - 0x80 }; - - if h.payload_length == 1 { - if !buf.has_remaining() { - return Err(DecodeError::InputTooShort) - } - if buf[0] < 0x80 { - return Err(DecodeError::NonCanonicalSingleByte) - } - } - - h - } else if b < 0xC0 { - buf.advance(1); - let len_of_len = b as usize - 0xB7; - if buf.len() < len_of_len { - return Err(DecodeError::InputTooShort) - } - let payload_length = usize::try_from(u64::from_be_bytes( - static_left_pad(&buf[..len_of_len]).ok_or(DecodeError::LeadingZero)?, - )) - .map_err(|_| DecodeError::Custom("Input too big"))?; - buf.advance(len_of_len); - if payload_length < 56 { - return Err(DecodeError::NonCanonicalSize) - } - - Self { list: false, payload_length } - } else if b < 0xF8 { - buf.advance(1); - Self { list: true, payload_length: b as usize - 0xC0 } - } else { - buf.advance(1); - let list = true; - let len_of_len = b as usize - 0xF7; - if buf.len() < len_of_len { - return Err(DecodeError::InputTooShort) - } - let payload_length = usize::try_from(u64::from_be_bytes( - static_left_pad(&buf[..len_of_len]).ok_or(DecodeError::LeadingZero)?, - )) - .map_err(|_| DecodeError::Custom("Input too big"))?; - buf.advance(len_of_len); - if payload_length < 56 { - return Err(DecodeError::NonCanonicalSize) - } - - Self { list, payload_length } - } - }; - - if buf.remaining() < h.payload_length { - return Err(DecodeError::InputTooShort) - } - - Ok(h) - } -} - -fn static_left_pad(data: &[u8]) -> Option<[u8; LEN]> { - if data.len() > LEN { - return None - } - - let mut v = [0; LEN]; - - if data.is_empty() { - return Some(v) - } - - if data[0] == 0 { - return None - } - - v[LEN - data.len()..].copy_from_slice(data); - Some(v) -} - -macro_rules! decode_integer { - ($t:ty) => { - impl Decodable for $t { - fn decode(buf: &mut &[u8]) -> Result { - let h = Header::decode(buf)?; - if h.list { - return Err(DecodeError::UnexpectedList) - } - if h.payload_length > (<$t>::BITS as usize / 8) { - return Err(DecodeError::Overflow) - } - if buf.remaining() < h.payload_length { - return Err(DecodeError::InputTooShort) - } - // In the case of 0x80, the Header will be decoded, leaving h.payload_length to be - // zero. - // 0x80 is the canonical encoding of 0, so we return 0 here. - if h.payload_length == 0 { - return Ok(<$t>::from(0u8)) - } - let v = <$t>::from_be_bytes( - static_left_pad(&buf[..h.payload_length]).ok_or(DecodeError::LeadingZero)?, - ); - buf.advance(h.payload_length); - Ok(v) - } - } - }; -} - -decode_integer!(usize); -decode_integer!(u8); -decode_integer!(u16); -decode_integer!(u32); -decode_integer!(u64); -decode_integer!(u128); - -impl Decodable for bool { - fn decode(buf: &mut &[u8]) -> Result { - Ok(match u8::decode(buf)? { - 0 => false, - 1 => true, - _ => return Err(DecodeError::Custom("invalid bool value, must be 0 or 1")), - }) - } -} - -#[cfg(feature = "std")] -impl Decodable for std::net::IpAddr { - fn decode(buf: &mut &[u8]) -> Result { - use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; - - let h = Header::decode(buf)?; - if h.list { - return Err(DecodeError::UnexpectedList) - } - let o = match h.payload_length { - 4 => { - let mut to = [0_u8; 4]; - to.copy_from_slice(&buf[..4]); - IpAddr::V4(Ipv4Addr::from(to)) - } - 16 => { - let mut to = [0u8; 16]; - to.copy_from_slice(&buf[..16]); - IpAddr::V6(Ipv6Addr::from(to)) - } - _ => return Err(DecodeError::UnexpectedLength), - }; - buf.advance(h.payload_length); - Ok(o) - } -} - -#[cfg(feature = "ethnum")] -decode_integer!(ethnum::U256); - -#[cfg(feature = "ethereum-types")] -mod ethereum_types_support { - use super::*; - use ethereum_types::*; - use revm_primitives::{ - alloy_primitives::{ - aliases::{B160, B64}, - Bloom, B512, - }, - ruint::aliases::{U128 as RU128, U256 as RU256, U64 as RU64}, - Address, FixedBytes, B256, - }; - - macro_rules! fixed_hash_impl { - ($t:ty) => { - impl Decodable for $t { - fn decode(buf: &mut &[u8]) -> Result { - Decodable::decode(buf).map(Self) - } - } - }; - } - - fixed_hash_impl!(B64); - fixed_hash_impl!(Address); - fixed_hash_impl!(B160); - fixed_hash_impl!(B256); - fixed_hash_impl!(B512); - fixed_hash_impl!(FixedBytes<256>); - fixed_hash_impl!(Bloom); - - fixed_hash_impl!(H64); - fixed_hash_impl!(H128); - fixed_hash_impl!(H160); - fixed_hash_impl!(H256); - fixed_hash_impl!(H512); - fixed_hash_impl!(H520); - - macro_rules! fixed_uint_impl { - ($t:ty, $n_bytes:tt) => { - impl Decodable for $t { - fn decode(buf: &mut &[u8]) -> Result { - let h = Header::decode(buf)?; - if h.list { - return Err(DecodeError::UnexpectedList) - } - if h.payload_length > $n_bytes { - return Err(DecodeError::Overflow) - } - if buf.remaining() < h.payload_length { - return Err(DecodeError::InputTooShort) - } - // In the case of 0x80, the Header will be decoded, leaving h.payload_length to - // be zero. - // 0x80 is the canonical encoding of 0, so we return 0 here. - if h.payload_length == 0 { - return Ok(<$t>::from(0u8)) - } - let n = <$t>::from_big_endian( - &static_left_pad::<$n_bytes>(&buf[..h.payload_length]) - .ok_or(DecodeError::LeadingZero)?, - ); - buf.advance(h.payload_length); - Ok(n) - } - } - }; - } - - macro_rules! fixed_revm_uint_impl { - ($t:ty, $n_bytes:tt) => { - impl Decodable for $t { - fn decode(buf: &mut &[u8]) -> Result { - let h = Header::decode(buf)?; - if h.list { - return Err(DecodeError::UnexpectedList) - } - if h.payload_length > $n_bytes { - return Err(DecodeError::Overflow) - } - if buf.remaining() < h.payload_length { - return Err(DecodeError::InputTooShort) - } - // In the case of 0x80, the Header will be decoded, leaving h.payload_length to - // be zero. - // 0x80 is the canonical encoding of 0, so we return 0 here. - if h.payload_length == 0 { - return Ok(<$t>::from(0u8)) - } - let n = <$t>::from_be_bytes( - static_left_pad::<$n_bytes>(&buf[..h.payload_length]) - .ok_or(DecodeError::LeadingZero)?, - ); - buf.advance(h.payload_length); - Ok(n) - } - } - }; - } - - fixed_revm_uint_impl!(RU64, 8); - fixed_revm_uint_impl!(RU128, 16); - fixed_revm_uint_impl!(RU256, 32); - - fixed_uint_impl!(U64, 8); - fixed_uint_impl!(U128, 16); - fixed_uint_impl!(U256, 32); - fixed_uint_impl!(U512, 64); -} - -impl Decodable for [u8; N] { - fn decode(from: &mut &[u8]) -> Result { - let h = Header::decode(from)?; - if h.list { - return Err(DecodeError::UnexpectedList) - } - if h.payload_length != N { - return Err(DecodeError::UnexpectedLength) - } - - let mut to = [0_u8; N]; - to.copy_from_slice(&from[..N]); - from.advance(N); - - Ok(to) - } -} - -impl Decodable for BytesMut { - fn decode(from: &mut &[u8]) -> Result { - let h = Header::decode(from)?; - if h.list { - return Err(DecodeError::UnexpectedList) - } - let mut to = BytesMut::with_capacity(h.payload_length); - to.extend_from_slice(&from[..h.payload_length]); - from.advance(h.payload_length); - - Ok(to) - } -} - -impl Decodable for Bytes { - fn decode(buf: &mut &[u8]) -> Result { - BytesMut::decode(buf).map(BytesMut::freeze) - } -} - -pub struct Rlp<'a> { - payload_view: &'a [u8], -} - -impl<'a> Rlp<'a> { - pub fn new(mut payload: &'a [u8]) -> Result { - let h = Header::decode(&mut payload)?; - if !h.list { - return Err(DecodeError::UnexpectedString) - } - - let payload_view = &payload[..h.payload_length]; - Ok(Self { payload_view }) - } - - pub fn get_next(&mut self) -> Result, DecodeError> { - if self.payload_view.is_empty() { - return Ok(None) - } - - Ok(Some(T::decode(&mut self.payload_view)?)) - } -} - -#[cfg(feature = "alloc")] -impl Decodable for alloc::vec::Vec -where - E: Decodable, -{ - fn decode(buf: &mut &[u8]) -> Result { - let h = Header::decode(buf)?; - if !h.list { - return Err(DecodeError::UnexpectedString) - } - - let payload_view = &mut &buf[..h.payload_length]; - - let mut to = alloc::vec::Vec::new(); - while !payload_view.is_empty() { - to.push(E::decode(payload_view)?); - } - - buf.advance(h.payload_length); - - Ok(to) - } -} - -impl Decodable for revm_primitives::Bytes { - fn decode(buf: &mut &[u8]) -> Result { - bytes::Bytes::decode(buf).map(Self) - } -} - -#[cfg(feature = "smol_str")] -impl Decodable for smol_str::SmolStr { - fn decode(from: &mut &[u8]) -> Result { - let h = Header::decode(from)?; - if h.list { - return Err(DecodeError::UnexpectedList) - } - let data = &from[..h.payload_length]; - let s = match core::str::from_utf8(data) { - Ok(s) => Ok(smol_str::SmolStr::from(s)), - Err(_) => Err(DecodeError::Custom("invalid string")), - }; - from.advance(h.payload_length); - s - } -} - -#[cfg(test)] -mod tests { - extern crate alloc; - - use super::*; - use crate::Encodable; - use alloc::vec; - use core::fmt::Debug; - use ethereum_types::{U128, U256, U512, U64}; - use ethnum::AsU256; - use hex_literal::hex; - - fn check_decode<'a, T, IT>(fixtures: IT) - where - T: Decodable + PartialEq + Debug, - IT: IntoIterator, &'a [u8])>, - { - for (expected, mut input) in fixtures { - assert_eq!(T::decode(&mut input), expected); - if expected.is_ok() { - assert!(input.is_empty()); - } - } - } - - fn check_decode_list(fixtures: IT) - where - T: Decodable + PartialEq + Debug, - IT: IntoIterator, DecodeError>, &'static [u8])>, - { - for (expected, mut input) in fixtures { - assert_eq!(vec::Vec::::decode(&mut input), expected); - if expected.is_ok() { - assert!(input.is_empty()); - } - } - } - - #[test] - fn rlp_strings() { - check_decode::(vec![ - (Ok(hex!("00")[..].to_vec().into()), &hex!("00")[..]), - ( - Ok(hex!("6f62636465666768696a6b6c6d")[..].to_vec().into()), - &hex!("8D6F62636465666768696A6B6C6D")[..], - ), - (Err(DecodeError::UnexpectedList), &hex!("C0")[..]), - ]) - } - - #[test] - fn rlp_fixed_length() { - check_decode(vec![ - (Ok(hex!("6f62636465666768696a6b6c6d")), &hex!("8D6F62636465666768696A6B6C6D")[..]), - (Err(DecodeError::UnexpectedLength), &hex!("8C6F62636465666768696A6B6C")[..]), - (Err(DecodeError::UnexpectedLength), &hex!("8E6F62636465666768696A6B6C6D6E")[..]), - ]) - } - - #[test] - fn rlp_u64() { - check_decode(vec![ - (Ok(9_u64), &hex!("09")[..]), - (Ok(0_u64), &hex!("80")[..]), - (Ok(0x0505_u64), &hex!("820505")[..]), - (Ok(0xCE05050505_u64), &hex!("85CE05050505")[..]), - (Err(DecodeError::Overflow), &hex!("8AFFFFFFFFFFFFFFFFFF7C")[..]), - (Err(DecodeError::InputTooShort), &hex!("8BFFFFFFFFFFFFFFFFFF7C")[..]), - (Err(DecodeError::UnexpectedList), &hex!("C0")[..]), - (Err(DecodeError::LeadingZero), &hex!("00")[..]), - (Err(DecodeError::NonCanonicalSingleByte), &hex!("8105")[..]), - (Err(DecodeError::LeadingZero), &hex!("8200F4")[..]), - (Err(DecodeError::NonCanonicalSize), &hex!("B8020004")[..]), - ( - Err(DecodeError::Overflow), - &hex!("A101000000000000000000000000000000000000008B000000000000000000000000")[..], - ), - ]) - } - - #[test] - fn rlp_u256() { - check_decode(vec![ - (Ok(9_u8.as_u256()), &hex!("09")[..]), - (Ok(0_u8.as_u256()), &hex!("80")[..]), - (Ok(0x0505_u16.as_u256()), &hex!("820505")[..]), - (Ok(0xCE05050505_u64.as_u256()), &hex!("85CE05050505")[..]), - (Ok(0xFFFFFFFFFFFFFFFFFF7C_u128.as_u256()), &hex!("8AFFFFFFFFFFFFFFFFFF7C")[..]), - (Err(DecodeError::InputTooShort), &hex!("8BFFFFFFFFFFFFFFFFFF7C")[..]), - (Err(DecodeError::UnexpectedList), &hex!("C0")[..]), - (Err(DecodeError::LeadingZero), &hex!("00")[..]), - (Err(DecodeError::NonCanonicalSingleByte), &hex!("8105")[..]), - (Err(DecodeError::LeadingZero), &hex!("8200F4")[..]), - (Err(DecodeError::NonCanonicalSize), &hex!("B8020004")[..]), - ( - Err(DecodeError::Overflow), - &hex!("A101000000000000000000000000000000000000008B000000000000000000000000")[..], - ), - ]) - } - - #[cfg(feature = "ethereum-types")] - #[test] - fn rlp_ethereum_types_u64() { - check_decode(vec![ - (Ok(U64::from(9_u8)), &hex!("09")[..]), - (Ok(U64::from(0_u8)), &hex!("80")[..]), - (Ok(U64::from(0x0505_u16)), &hex!("820505")[..]), - (Ok(U64::from(0xCE05050505_u64)), &hex!("85CE05050505")[..]), - (Err(DecodeError::Overflow), &hex!("8AFFFFFFFFFFFFFFFFFF7C")[..]), - (Err(DecodeError::InputTooShort), &hex!("8BFFFFFFFFFFFFFFFFFF7C")[..]), - (Err(DecodeError::UnexpectedList), &hex!("C0")[..]), - (Err(DecodeError::LeadingZero), &hex!("00")[..]), - (Err(DecodeError::NonCanonicalSingleByte), &hex!("8105")[..]), - (Err(DecodeError::LeadingZero), &hex!("8200F4")[..]), - (Err(DecodeError::NonCanonicalSize), &hex!("B8020004")[..]), - ( - Err(DecodeError::Overflow), - &hex!("A101000000000000000000000000000000000000008B000000000000000000000000")[..], - ), - ]) - } - - #[cfg(feature = "ethereum-types")] - #[test] - fn rlp_ethereum_types_u128() { - check_decode(vec![ - (Ok(U128::from(9_u8)), &hex!("09")[..]), - (Ok(U128::from(0_u8)), &hex!("80")[..]), - (Ok(U128::from(0x0505_u16)), &hex!("820505")[..]), - (Ok(U128::from(0xCE05050505_u64)), &hex!("85CE05050505")[..]), - (Ok(U128::from(0xFFFFFFFFFFFFFFFFFF7C_u128)), &hex!("8AFFFFFFFFFFFFFFFFFF7C")[..]), - (Err(DecodeError::InputTooShort), &hex!("8BFFFFFFFFFFFFFFFFFF7C")[..]), - (Err(DecodeError::UnexpectedList), &hex!("C0")[..]), - (Err(DecodeError::LeadingZero), &hex!("00")[..]), - (Err(DecodeError::NonCanonicalSingleByte), &hex!("8105")[..]), - (Err(DecodeError::LeadingZero), &hex!("8200F4")[..]), - (Err(DecodeError::NonCanonicalSize), &hex!("B8020004")[..]), - ( - Err(DecodeError::Overflow), - &hex!("A101000000000000000000000000000000000000008B000000000000000000000000")[..], - ), - ]) - } - - #[cfg(feature = "ethereum-types")] - #[test] - fn rlp_ethereum_types_u256() { - check_decode(vec![ - (Ok(U256::from(9_u8)), &hex!("09")[..]), - (Ok(U256::from(0_u8)), &hex!("80")[..]), - (Ok(U256::from(0x0505_u16)), &hex!("820505")[..]), - (Ok(U256::from(0xCE05050505_u64)), &hex!("85CE05050505")[..]), - (Ok(U256::from(0xFFFFFFFFFFFFFFFFFF7C_u128)), &hex!("8AFFFFFFFFFFFFFFFFFF7C")[..]), - (Err(DecodeError::InputTooShort), &hex!("8BFFFFFFFFFFFFFFFFFF7C")[..]), - (Err(DecodeError::UnexpectedList), &hex!("C0")[..]), - (Err(DecodeError::LeadingZero), &hex!("00")[..]), - (Err(DecodeError::NonCanonicalSingleByte), &hex!("8105")[..]), - (Err(DecodeError::LeadingZero), &hex!("8200F4")[..]), - (Err(DecodeError::NonCanonicalSize), &hex!("B8020004")[..]), - ( - Err(DecodeError::Overflow), - &hex!("A101000000000000000000000000000000000000008B000000000000000000000000")[..], - ), - ]) - } - - #[cfg(feature = "ethereum-types")] - #[test] - fn rlp_ethereum_types_u512() { - check_decode(vec![ - (Ok(U512::from(9_u8)), &hex!("09")[..]), - (Ok(U512::from(0_u8)), &hex!("80")[..]), - (Ok(U512::from(0x0505_u16)), &hex!("820505")[..]), - (Ok(U512::from(0xCE05050505_u64)), &hex!("85CE05050505")[..]), - ( - Ok(U512::from(0xFFFFFFFFFFFFFFFFFF7C_u128)), - &hex!("8AFFFFFFFFFFFFFFFFFF7C")[..], - ), - ( - Err(DecodeError::InputTooShort), - &hex!("8BFFFFFFFFFFFFFFFFFF7C")[..], - ), - (Err(DecodeError::UnexpectedList), &hex!("C0")[..]), - (Err(DecodeError::LeadingZero), &hex!("00")[..]), - (Err(DecodeError::NonCanonicalSingleByte), &hex!("8105")[..]), - (Err(DecodeError::LeadingZero), &hex!("8200F4")[..]), - (Err(DecodeError::NonCanonicalSize), &hex!("B8020004")[..]), - ( - Ok(U512::from_dec_str("115792089237316195423570985008687907853269984676653278628940326933415738736640").unwrap()), - &hex!("A101000000000000000000000000000000000000008B000000000000000000000000")[..], - ), - ( - Err(DecodeError::Overflow), - &hex!("B84101000000000000000000000000000000000000008B000000000000000000000000000000000000000000000000000000000000008B000000000000000000000000")[..], - ), - ]) - } - - #[test] - fn rlp_vectors() { - check_decode_list(vec![ - (Ok(vec![]), &hex!("C0")[..]), - (Ok(vec![0xBBCCB5_u64, 0xFFC0B5_u64]), &hex!("C883BBCCB583FFC0B5")[..]), - ]) - } - - #[cfg(feature = "smol_str")] - #[test] - fn rlp_smol_str() { - use smol_str::SmolStr; - let mut b = BytesMut::new(); - "test smol str".to_string().encode(&mut b); - check_decode::(vec![ - (Ok(SmolStr::new("test smol str")), b.as_ref()), - (Err(DecodeError::UnexpectedList), &hex!("C0")[..]), - ]) - } -} diff --git a/crates/rlp/src/encode.rs b/crates/rlp/src/encode.rs deleted file mode 100644 index 7ec8ca1b82c..00000000000 --- a/crates/rlp/src/encode.rs +++ /dev/null @@ -1,754 +0,0 @@ -use crate::types::*; -use arrayvec::ArrayVec; -use auto_impl::auto_impl; -use bytes::{BufMut, Bytes, BytesMut}; -use core::borrow::Borrow; - -macro_rules! to_be_bytes_trimmed { - ($be:ident, $x:expr) => {{ - $be = $x.to_be_bytes(); - &$be[($x.leading_zeros() / 8) as usize..] - }}; -} - -impl Header { - /// Encodes the header into the `out` buffer. - pub fn encode(&self, out: &mut dyn BufMut) { - if self.payload_length < 56 { - let code = if self.list { EMPTY_LIST_CODE } else { EMPTY_STRING_CODE }; - out.put_u8(code + self.payload_length as u8); - } else { - let len_be; - let len_be = to_be_bytes_trimmed!(len_be, self.payload_length); - let code = if self.list { 0xF7 } else { 0xB7 }; - out.put_u8(code + len_be.len() as u8); - out.put_slice(len_be); - } - } - - /// Returns the length of the encoded header - pub fn length(&self) -> usize { - let mut out = BytesMut::new(); - self.encode(&mut out); - out.len() - } -} - -pub const fn length_of_length(payload_length: usize) -> usize { - if payload_length < 56 { - 1 - } else { - 1 + 8 - payload_length.leading_zeros() as usize / 8 - } -} - -#[doc(hidden)] -pub const fn const_add(a: usize, b: usize) -> usize { - a + b -} - -/// A trait for types that have a maximum encoded length. -/// -/// # Safety -/// Invalid value can cause the encoder to crash. -#[doc(hidden)] -pub unsafe trait MaxEncodedLen: Encodable {} - -/// A trait for types that have a maximum encoded length. -/// -/// # Safety -/// Invalid value can cause the encoder to crash. -#[doc(hidden)] -pub unsafe trait MaxEncodedLenAssoc: Encodable { - const LEN: usize; -} - -/// Use this to define length of an encoded entity -/// -/// # Safety -/// Invalid value can cause the encoder to crash. -#[macro_export] -macro_rules! impl_max_encoded_len { - ($t:ty, $len:block) => { - unsafe impl MaxEncodedLen<{ $len }> for $t {} - unsafe impl MaxEncodedLenAssoc for $t { - const LEN: usize = $len; - } - }; -} - -#[auto_impl(&)] -#[cfg_attr(feature = "alloc", auto_impl(Box, Arc))] -pub trait Encodable { - /// Appends the rlp encoded object to the specified output buffer. - fn encode(&self, out: &mut dyn BufMut); - - /// Returns the length of the encoded object. - /// - /// NOTE: This includes the length of the rlp [Header]. - fn length(&self) -> usize { - let mut out = BytesMut::new(); - self.encode(&mut out); - out.len() - } -} - -impl<'a> Encodable for &'a [u8] { - fn encode(&self, out: &mut dyn BufMut) { - if self.len() != 1 || self[0] >= EMPTY_STRING_CODE { - Header { list: false, payload_length: self.len() }.encode(out); - } - out.put_slice(self); - } - - fn length(&self) -> usize { - let mut len = self.len(); - if self.len() != 1 || self[0] >= EMPTY_STRING_CODE { - len += length_of_length(self.len()); - } - len - } -} - -impl Encodable for [u8; LEN] { - fn encode(&self, out: &mut dyn BufMut) { - (self as &[u8]).encode(out) - } - - fn length(&self) -> usize { - (self as &[u8]).length() - } -} - -unsafe impl MaxEncodedLenAssoc for [u8; LEN] { - const LEN: usize = LEN + length_of_length(LEN); -} - -macro_rules! encodable_uint { - ($t:ty) => { - #[allow(clippy::cmp_owned)] - impl Encodable for $t { - fn length(&self) -> usize { - if *self < <$t>::from(EMPTY_STRING_CODE) { - 1 - } else { - 1 + (<$t>::BITS as usize / 8) - (self.leading_zeros() as usize / 8) - } - } - - fn encode(&self, out: &mut dyn BufMut) { - if *self == 0 { - out.put_u8(EMPTY_STRING_CODE); - } else if *self < <$t>::from(EMPTY_STRING_CODE) { - out.put_u8(u8::try_from(*self).unwrap()); - } else { - let be; - let be = to_be_bytes_trimmed!(be, *self); - out.put_u8(EMPTY_STRING_CODE + be.len() as u8); - out.put_slice(be); - } - } - } - }; -} - -macro_rules! max_encoded_len_uint { - ($t:ty) => { - impl_max_encoded_len!($t, { - length_of_length(<$t>::MAX.to_be_bytes().len()) + <$t>::MAX.to_be_bytes().len() - }); - }; -} - -encodable_uint!(usize); -max_encoded_len_uint!(usize); - -encodable_uint!(u8); -max_encoded_len_uint!(u8); - -encodable_uint!(u16); -max_encoded_len_uint!(u16); - -encodable_uint!(u32); -max_encoded_len_uint!(u32); - -encodable_uint!(u64); -max_encoded_len_uint!(u64); - -encodable_uint!(u128); -max_encoded_len_uint!(u128); - -impl Encodable for bool { - fn encode(&self, out: &mut dyn BufMut) { - (*self as u8).encode(out) - } - - fn length(&self) -> usize { - (*self as u8).length() - } -} - -impl_max_encoded_len!(bool, { ::LEN }); - -#[cfg(feature = "smol_str")] -impl Encodable for smol_str::SmolStr { - fn encode(&self, out: &mut dyn BufMut) { - self.as_bytes().encode(out); - } - fn length(&self) -> usize { - self.as_bytes().length() - } -} - -#[cfg(feature = "std")] -impl Encodable for std::net::IpAddr { - fn encode(&self, out: &mut dyn BufMut) { - match self { - std::net::IpAddr::V4(ref o) => (&o.octets()[..]).encode(out), - std::net::IpAddr::V6(ref o) => (&o.octets()[..]).encode(out), - } - } -} - -#[cfg(feature = "ethnum")] -mod ethnum_support { - use super::*; - - encodable_uint!(ethnum::U256); - impl_max_encoded_len!(ethnum::U256, { length_of_length(32) + 32 }); -} - -#[cfg(feature = "ethereum-types")] -mod ethereum_types_support { - use super::*; - use ethereum_types::*; - use revm_primitives::{ - alloy_primitives::B512, - ruint::aliases::{U128 as RU128, U256 as RU256, U64 as RU64}, - Address, B256, - }; - - macro_rules! fixed_hash_impl { - ($t:ty) => { - impl Encodable for $t { - fn length(&self) -> usize { - self.0.length() - } - - fn encode(&self, out: &mut dyn bytes::BufMut) { - self.0.encode(out) - } - } - impl_max_encoded_len!($t, { length_of_length(<$t>::len_bytes()) + <$t>::len_bytes() }); - }; - } - - fixed_hash_impl!(Address); - fixed_hash_impl!(B256); - fixed_hash_impl!(B512); - fixed_hash_impl!(Bloom); - - fixed_hash_impl!(H64); - fixed_hash_impl!(H128); - fixed_hash_impl!(H160); - fixed_hash_impl!(H256); - fixed_hash_impl!(H512); - fixed_hash_impl!(H520); - - macro_rules! fixed_uint_impl { - ($t:ty, $n_bytes:tt) => { - impl Encodable for $t { - fn length(&self) -> usize { - if *self < <$t>::from(EMPTY_STRING_CODE) { - 1 - } else { - 1 + $n_bytes - (self.leading_zeros() as usize / 8) - } - } - - fn encode(&self, out: &mut dyn bytes::BufMut) { - let mut temp_arr = [0u8; $n_bytes]; - self.to_big_endian(&mut temp_arr[..]); - // cut the leading zeros after converting to big endian - let sliced = &temp_arr[(self.leading_zeros() / 8) as usize..]; - sliced.encode(out); - } - } - }; - } - - fixed_uint_impl!(U64, 8); - fixed_uint_impl!(U128, 16); - fixed_uint_impl!(U256, 32); - fixed_uint_impl!(U512, 64); - - macro_rules! fixed_revm_uint_impl { - ($t:ty, $n_bytes:tt) => { - impl Encodable for $t { - fn length(&self) -> usize { - if *self < <$t>::from(EMPTY_STRING_CODE) { - 1 - } else { - 1 + self.byte_len() - } - } - - fn encode(&self, out: &mut dyn bytes::BufMut) { - let be = self.to_be_bytes::<$n_bytes>(); - (&be[self.leading_zeros() / 8..]).encode(out); - } - } - }; - } - - fixed_revm_uint_impl!(RU64, 8); - fixed_revm_uint_impl!(RU128, 16); - fixed_revm_uint_impl!(RU256, 32); - impl_max_encoded_len!(RU256, { length_of_length(32) + 32 }); -} - -macro_rules! slice_impl { - ($t:ty) => { - impl $crate::Encodable for $t { - fn length(&self) -> usize { - (&self[..]).length() - } - - fn encode(&self, out: &mut dyn bytes::BufMut) { - (&self[..]).encode(out) - } - } - }; -} - -#[cfg(feature = "alloc")] -mod alloc_support { - use super::*; - - extern crate alloc; - - impl Encodable for ::alloc::vec::Vec - where - T: Encodable, - { - fn encode(&self, out: &mut dyn BufMut) { - encode_list(self, out) - } - - fn length(&self) -> usize { - list_length(self) - } - } - - impl Encodable for ::alloc::string::String { - fn encode(&self, out: &mut dyn BufMut) { - self.as_bytes().encode(out); - } - fn length(&self) -> usize { - self.as_bytes().length() - } - } -} - -impl Encodable for &str { - fn encode(&self, out: &mut dyn BufMut) { - self.as_bytes().encode(out); - } - fn length(&self) -> usize { - self.as_bytes().length() - } -} - -slice_impl!(Bytes); -slice_impl!(revm_primitives::Bytes); -slice_impl!(BytesMut); - -fn rlp_list_header(v: &[K]) -> Header -where - E: Encodable + ?Sized, - K: Borrow, -{ - let mut h = Header { list: true, payload_length: 0 }; - for x in v { - h.payload_length += x.borrow().length(); - } - h -} - -pub fn list_length(v: &[K]) -> usize -where - E: Encodable, - K: Borrow, -{ - let payload_length = rlp_list_header(v).payload_length; - length_of_length(payload_length) + payload_length -} - -/// RLP encode the list of items. -pub fn encode_list(v: &[K], out: &mut dyn BufMut) -where - E: Encodable + ?Sized, - K: Borrow, -{ - let h = rlp_list_header(v); - h.encode(out); - for x in v { - x.borrow().encode(out); - } -} - -/// RLP encode an iterator over items. -/// -/// NOTE: This function clones the iterator. If the items are expensive to clone, consider -/// using [encode_list] instead. -pub fn encode_iter(i: impl Iterator + Clone, out: &mut dyn BufMut) -where - K: Encodable, -{ - let mut h = Header { list: true, payload_length: 0 }; - for x in i.clone() { - h.payload_length += x.length(); - } - - h.encode(out); - for x in i { - x.encode(out); - } -} - -pub fn encode_fixed_size, const LEN: usize>(v: &E) -> ArrayVec { - let mut out = ArrayVec::from([0_u8; LEN]); - - let mut s = out.as_mut_slice(); - - v.encode(&mut s); - - let final_len = LEN - s.len(); - out.truncate(final_len); - - out -} - -#[cfg(feature = "kzg")] -mod kzg_support { - extern crate c_kzg; - - use super::BufMut; - use crate::{Decodable, DecodeError, Encodable}; - use c_kzg::{Blob, Bytes48, KzgCommitment, KzgProof, BYTES_PER_BLOB, BYTES_PER_COMMITMENT}; - use core::ops::Deref; - - impl Encodable for Blob { - fn encode(&self, out: &mut dyn BufMut) { - // Deref is implemented to get the underlying bytes - self.deref().encode(out); - } - - fn length(&self) -> usize { - self.deref().length() - } - } - - impl Decodable for Blob { - fn decode(buf: &mut &[u8]) -> Result { - let bytes: [u8; BYTES_PER_BLOB] = Decodable::decode(buf)?; - Ok(Blob::from(bytes)) - } - } - - impl Encodable for Bytes48 { - fn encode(&self, out: &mut dyn BufMut) { - self.deref().encode(out); - } - - fn length(&self) -> usize { - self.deref().length() - } - } - - impl Decodable for Bytes48 { - fn decode(buf: &mut &[u8]) -> Result { - let bytes: [u8; BYTES_PER_COMMITMENT] = Decodable::decode(buf)?; - Ok(Bytes48::from(bytes)) - } - } - - /// Only [Encodable] is implemented for [KzgCommitment] because this is a validated type - it - /// should be decoded using [Decodable] into a [Bytes48] type, validated, _then_ converted - /// into a [KzgCommitment]. - impl Encodable for KzgCommitment { - fn encode(&self, out: &mut dyn BufMut) { - self.deref().encode(out); - } - - fn length(&self) -> usize { - self.deref().length() - } - } - - /// Only [Encodable] is implemented for [KzgProof] because this is a validated type - it should - /// be decoded using [Decodable] into a [Bytes48] type, validated, _then_ converted into a - /// [KzgProof]. - impl Encodable for KzgProof { - fn encode(&self, out: &mut dyn BufMut) { - self.deref().encode(out); - } - - fn length(&self) -> usize { - self.deref().length() - } - } -} - -#[cfg(test)] -mod tests { - extern crate alloc; - - use super::*; - use alloc::vec; - use bytes::BytesMut; - use hex_literal::hex; - - fn encoded(t: T) -> BytesMut { - let mut out = BytesMut::new(); - t.encode(&mut out); - out - } - - fn encoded_list(t: &[T]) -> BytesMut { - let mut out1 = BytesMut::new(); - encode_list(t, &mut out1); - - let v = t.to_vec(); - assert_eq!(out1.len(), v.length()); - - let mut out2 = BytesMut::new(); - v.encode(&mut out2); - assert_eq!(out1, out2); - - out1 - } - - fn encoded_iter<'a, T: Encodable + 'a>(iter: impl Iterator + Clone) -> BytesMut { - let mut out = BytesMut::new(); - encode_iter(iter, &mut out); - out - } - - #[test] - fn rlp_str() { - assert_eq!(encoded("")[..], hex!("80")[..]); - assert_eq!(encoded("{")[..], hex!("7b")[..]); - assert_eq!(encoded("test str")[..], hex!("887465737420737472")[..]); - } - - #[test] - fn rlp_strings() { - assert_eq!(encoded(hex!(""))[..], hex!("80")[..]); - assert_eq!(encoded(hex!("7B"))[..], hex!("7b")[..]); - assert_eq!(encoded(hex!("80"))[..], hex!("8180")[..]); - assert_eq!(encoded(hex!("ABBA"))[..], hex!("82abba")[..]); - } - - fn u8_fixtures() -> impl IntoIterator { - vec![ - (0, &hex!("80")[..]), - (1, &hex!("01")[..]), - (0x7F, &hex!("7F")[..]), - (0x80, &hex!("8180")[..]), - ] - } - - fn c>( - it: impl IntoIterator, - ) -> impl Iterator { - it.into_iter().map(|(k, v)| (k.into(), v)) - } - - fn u16_fixtures() -> impl IntoIterator { - c(u8_fixtures()).chain(vec![(0x400, &hex!("820400")[..])]) - } - - fn u32_fixtures() -> impl IntoIterator { - c(u16_fixtures()) - .chain(vec![(0xFFCCB5, &hex!("83ffccb5")[..]), (0xFFCCB5DD, &hex!("84ffccb5dd")[..])]) - } - - fn u64_fixtures() -> impl IntoIterator { - c(u32_fixtures()).chain(vec![ - (0xFFCCB5DDFF, &hex!("85ffccb5ddff")[..]), - (0xFFCCB5DDFFEE, &hex!("86ffccb5ddffee")[..]), - (0xFFCCB5DDFFEE14, &hex!("87ffccb5ddffee14")[..]), - (0xFFCCB5DDFFEE1483, &hex!("88ffccb5ddffee1483")[..]), - ]) - } - - fn u128_fixtures() -> impl IntoIterator { - c(u64_fixtures()).chain(vec![( - 0x10203E405060708090A0B0C0D0E0F2, - &hex!("8f10203e405060708090a0b0c0d0e0f2")[..], - )]) - } - - #[cfg(feature = "ethnum")] - fn u256_fixtures() -> impl IntoIterator { - c(u128_fixtures()).chain(vec![( - ethnum::U256::from_str_radix( - "0100020003000400050006000700080009000A0B4B000C000D000E01", - 16, - ) - .unwrap(), - &hex!("9c0100020003000400050006000700080009000a0b4b000c000d000e01")[..], - )]) - } - - #[cfg(feature = "ethereum-types")] - fn eth_u64_fixtures() -> impl IntoIterator { - c(u64_fixtures()).chain(vec![ - ( - ethereum_types::U64::from_str_radix("FFCCB5DDFF", 16).unwrap(), - &hex!("85ffccb5ddff")[..], - ), - ( - ethereum_types::U64::from_str_radix("FFCCB5DDFFEE", 16).unwrap(), - &hex!("86ffccb5ddffee")[..], - ), - ( - ethereum_types::U64::from_str_radix("FFCCB5DDFFEE14", 16).unwrap(), - &hex!("87ffccb5ddffee14")[..], - ), - ( - ethereum_types::U64::from_str_radix("FFCCB5DDFFEE1483", 16).unwrap(), - &hex!("88ffccb5ddffee1483")[..], - ), - ]) - } - - #[cfg(feature = "ethereum-types")] - fn eth_u128_fixtures() -> impl IntoIterator { - c(u128_fixtures()).chain(vec![( - ethereum_types::U128::from_str_radix("10203E405060708090A0B0C0D0E0F2", 16).unwrap(), - &hex!("8f10203e405060708090a0b0c0d0e0f2")[..], - )]) - } - - #[cfg(feature = "ethereum-types")] - fn eth_u256_fixtures() -> impl IntoIterator { - c(u128_fixtures()).chain(vec![( - ethereum_types::U256::from_str_radix( - "0100020003000400050006000700080009000A0B4B000C000D000E01", - 16, - ) - .unwrap(), - &hex!("9c0100020003000400050006000700080009000a0b4b000c000d000e01")[..], - )]) - } - - #[cfg(feature = "ethereum-types")] - fn eth_u512_fixtures() -> impl IntoIterator { - c(eth_u256_fixtures()).chain(vec![( - ethereum_types::U512::from_str_radix( - "0100020003000400050006000700080009000A0B4B000C000D000E010100020003000400050006000700080009000A0B4B000C000D000E01", - 16, - ) - .unwrap(), - &hex!("b8380100020003000400050006000700080009000A0B4B000C000D000E010100020003000400050006000700080009000A0B4B000C000D000E01")[..], - )]) - } - - macro_rules! uint_rlp_test { - ($fixtures:expr) => { - for (input, output) in $fixtures { - assert_eq!(encoded(input), output); - } - }; - } - - #[test] - fn rlp_uints() { - uint_rlp_test!(u8_fixtures()); - uint_rlp_test!(u16_fixtures()); - uint_rlp_test!(u32_fixtures()); - uint_rlp_test!(u64_fixtures()); - uint_rlp_test!(u128_fixtures()); - #[cfg(feature = "ethnum")] - uint_rlp_test!(u256_fixtures()); - } - - #[cfg(feature = "ethereum-types")] - #[test] - fn rlp_eth_uints() { - uint_rlp_test!(eth_u64_fixtures()); - uint_rlp_test!(eth_u128_fixtures()); - uint_rlp_test!(eth_u256_fixtures()); - uint_rlp_test!(eth_u512_fixtures()); - } - - #[test] - fn rlp_list() { - assert_eq!(encoded_list::(&[]), &hex!("c0")[..]); - assert_eq!(encoded_list::(&[0x00u8]), &hex!("c180")[..]); - assert_eq!(encoded_list(&[0xFFCCB5_u64, 0xFFC0B5_u64]), &hex!("c883ffccb583ffc0b5")[..]); - } - - #[test] - fn rlp_iter() { - assert_eq!(encoded_iter::([].iter()), &hex!("c0")[..]); - assert_eq!( - encoded_iter([0xFFCCB5_u64, 0xFFC0B5_u64].iter()), - &hex!("c883ffccb583ffc0b5")[..] - ); - } - - #[cfg(feature = "smol_str")] - #[test] - fn rlp_smol_str() { - use smol_str::SmolStr; - assert_eq!(encoded(SmolStr::new(""))[..], hex!("80")[..]); - let mut b = BytesMut::new(); - "test smol str".to_string().encode(&mut b); - assert_eq!(&encoded(SmolStr::new("test smol str"))[..], b.as_ref()); - let mut b = BytesMut::new(); - "abcdefgh".to_string().encode(&mut b); - assert_eq!(&encoded(SmolStr::new("abcdefgh"))[..], b.as_ref()); - } - - #[test] - fn to_be_bytes_trimmed() { - macro_rules! test_to_be_bytes_trimmed { - ($($x:expr => $expected:expr),+ $(,)?) => {$( - let be; - assert_eq!(to_be_bytes_trimmed!(be, $x), $expected); - )+}; - } - - test_to_be_bytes_trimmed! { - 0u8 => [], - 0u16 => [], - 0u32 => [], - 0u64 => [], - 0usize => [], - 0u128 => [], - - 1u8 => [1], - 1u16 => [1], - 1u32 => [1], - 1u64 => [1], - 1usize => [1], - 1u128 => [1], - - u8::MAX => [0xff], - u16::MAX => [0xff, 0xff], - u32::MAX => [0xff, 0xff, 0xff, 0xff], - u64::MAX => [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], - u128::MAX => [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff], - - 1u8 => [1], - 255u8 => [255], - 256u16 => [1, 0], - 65535u16 => [255, 255], - 65536u32 => [1, 0, 0], - 65536u64 => [1, 0, 0], - } - } -} diff --git a/crates/rlp/src/lib.rs b/crates/rlp/src/lib.rs deleted file mode 100644 index c9bf35e5c5b..00000000000 --- a/crates/rlp/src/lib.rs +++ /dev/null @@ -1,43 +0,0 @@ -#![cfg_attr(docsrs, feature(doc_cfg))] -#![doc( - html_logo_url = "https://raw.githubusercontent.com/paradigmxyz/reth/main/assets/reth-docs.png", - html_favicon_url = "https://avatars0.githubusercontent.com/u/97369466?s=256", - issue_tracker_base_url = "https://github.com/paradigmxzy/reth/issues/" -)] -#![warn(unreachable_pub)] -#![deny(unused_must_use)] -#![doc(test( - no_crate_inject, - attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables)) -))] -#![cfg_attr(not(feature = "std"), no_std)] - -//! A fast RLP implementation. -//! -//! ## Feature Flags -//! -//! This crate works on `#[no_std]` targets if `std` is not enabled. -//! -//! - `derive`: Enables derive macros. -//! - `std`: Uses the Rust standard library. - -#[cfg(feature = "alloc")] -extern crate alloc; - -mod decode; -mod encode; -mod types; - -pub use bytes::BufMut; - -pub use decode::{Decodable, DecodeError, Rlp}; -pub use encode::{ - const_add, encode_fixed_size, encode_iter, encode_list, length_of_length, list_length, - Encodable, MaxEncodedLen, MaxEncodedLenAssoc, -}; -pub use types::*; - -#[cfg(feature = "derive")] -pub use reth_rlp_derive::{ - RlpDecodable, RlpDecodableWrapper, RlpEncodable, RlpEncodableWrapper, RlpMaxEncodedLen, -}; diff --git a/crates/rlp/src/types.rs b/crates/rlp/src/types.rs deleted file mode 100644 index 4cbc6f10f63..00000000000 --- a/crates/rlp/src/types.rs +++ /dev/null @@ -1,8 +0,0 @@ -#[derive(Debug, Clone, Default, PartialEq, Eq)] -pub struct Header { - pub list: bool, - pub payload_length: usize, -} - -pub const EMPTY_STRING_CODE: u8 = 0x80; -pub const EMPTY_LIST_CODE: u8 = 0xC0; diff --git a/crates/rlp/tests/rlp.rs b/crates/rlp/tests/rlp.rs deleted file mode 100644 index c7c3e52e417..00000000000 --- a/crates/rlp/tests/rlp.rs +++ /dev/null @@ -1,135 +0,0 @@ -use bytes::{Bytes, BytesMut}; -use ethnum::U256; -use hex_literal::hex; -use reth_rlp::{DecodeError, *}; - -#[derive(Debug, PartialEq, RlpEncodable, RlpDecodable)] -struct Item { - a: Bytes, -} - -#[derive(Debug, PartialEq, RlpEncodable, RlpDecodable, RlpMaxEncodedLen)] -struct Test4Numbers { - a: u8, - b: u64, - c: U256, - #[rlp(skip)] - #[rlp(default)] - s: U256, - d: U256, -} - -#[derive(Debug, PartialEq, RlpEncodableWrapper, RlpDecodableWrapper)] -pub struct W(Test4Numbers); - -#[derive(Debug, PartialEq, RlpEncodable)] -struct Test4NumbersGenerics<'a, D: Encodable> { - a: u8, - b: u64, - c: &'a U256, - d: &'a D, -} - -#[derive(Debug, PartialEq, RlpEncodable, RlpDecodable)] -#[rlp(trailing)] -struct TestOpt { - a: u8, - b: u64, - c: Option, - d: Option, -} - -fn encoded(t: &T) -> BytesMut { - let mut out = BytesMut::new(); - t.encode(&mut out); - out -} - -#[test] -fn test_encode_item() { - let item = Item { a: b"dog".to_vec().into() }; - - let expected = vec![0xc4, 0x83, b'd', b'o', b'g']; - let out = encoded(&item); - assert_eq!(&*out, expected); - - let decoded = Decodable::decode(&mut &*expected).expect("decode failure"); - assert_eq!(item, decoded); - - let item = Test4Numbers { - a: 0x05, - b: 0xdeadbeefbaadcafe, - c: U256::from_be_bytes(hex!( - "56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" - )), - s: U256::from_be_bytes(hex!( - "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" - )), - d: U256::from_be_bytes(hex!( - "c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" - )), - }; - - let expected = hex!("f84c0588deadbeefbaadcafea056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").to_vec(); - let out = encoded(&item); - assert_eq!(&*out, expected); - - let out = reth_rlp::encode_fixed_size(&item); - assert_eq!(&*out, expected); - - let decoded: Test4Numbers = Decodable::decode(&mut &*expected).unwrap(); - assert_eq!(decoded.a, item.a); - assert_eq!(decoded.b, item.b); - assert_eq!(decoded.c, item.c); - assert_eq!(decoded.d, item.d); - assert_eq!(decoded.s, U256::ZERO); - - let mut rlp_view = Rlp::new(&expected).unwrap(); - assert_eq!(rlp_view.get_next().unwrap(), Some(item.a)); - assert_eq!(rlp_view.get_next().unwrap(), Some(item.b)); - assert_eq!(rlp_view.get_next().unwrap(), Some(item.c)); - assert_eq!(rlp_view.get_next().unwrap(), Some(item.d)); - assert_eq!(rlp_view.get_next::().unwrap(), None); - - assert_eq!( - encoded(&Test4NumbersGenerics { a: item.a, b: item.b, c: &item.c, d: &item.d }), - expected - ); - - assert_eq!(encoded(&W(item)), expected); - assert_eq!(W::decode(&mut &*expected).unwrap().0, decoded); - assert_eq!(Test4Numbers::LEN, 79); -} - -#[test] -fn invalid_decode_sideeffect() { - let fixture = hex!("f84d0588deadbeefbaadcafea056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470"); - let mut sl: &[u8] = &fixture; - - assert_eq!(Test4Numbers::decode(&mut sl), Err(DecodeError::InputTooShort)); - - assert_eq!(sl.len(), fixture.len()); -} - -#[test] -fn test_opt_fields_roundtrip() { - let expected = hex!("c20102"); - let item = TestOpt { a: 1, b: 2, c: None, d: None }; - assert_eq!(&*encoded(&item), expected); - assert_eq!(TestOpt::decode(&mut &expected[..]).unwrap(), item); - - let expected = hex!("c3010203"); - let item = TestOpt { a: 1, b: 2, c: Some(3), d: None }; - assert_eq!(&*encoded(&item), expected); - assert_eq!(TestOpt::decode(&mut &expected[..]).unwrap(), item); - - let expected = hex!("c401020304"); - let item = TestOpt { a: 1, b: 2, c: Some(3), d: Some(4) }; - assert_eq!(&*encoded(&item), expected); - assert_eq!(TestOpt::decode(&mut &expected[..]).unwrap(), item); - - let expected = hex!("c401028004"); - let item = TestOpt { a: 1, b: 2, c: None, d: Some(4) }; - assert_eq!(&*encoded(&item), expected); - assert_eq!(TestOpt::decode(&mut &expected[..]).unwrap(), item); -} diff --git a/crates/rpc/rpc-engine-api/Cargo.toml b/crates/rpc/rpc-engine-api/Cargo.toml index 7d8161c5db5..ebd0bfeb785 100644 --- a/crates/rpc/rpc-engine-api/Cargo.toml +++ b/crates/rpc/rpc-engine-api/Cargo.toml @@ -30,7 +30,7 @@ jsonrpsee-core.workspace = true tracing.workspace = true [dev-dependencies] -reth-rlp.workspace = true +alloy-rlp.workspace = true reth-interfaces = { workspace = true, features = ["test-utils"] } reth-provider = { workspace = true, features = ["test-utils"] } reth-payload-builder = { workspace = true, features = ["test-utils"] } diff --git a/crates/rpc/rpc-engine-api/src/lib.rs b/crates/rpc/rpc-engine-api/src/lib.rs index 92631faa10a..29dd8905446 100644 --- a/crates/rpc/rpc-engine-api/src/lib.rs +++ b/crates/rpc/rpc-engine-api/src/lib.rs @@ -37,5 +37,5 @@ pub use reth_rpc_api::EngineApiServer; #[allow(unused_imports)] mod tests { // silence unused import warning - use reth_rlp as _; + use alloy_rlp as _; } diff --git a/crates/rpc/rpc-engine-api/tests/it/payload.rs b/crates/rpc/rpc-engine-api/tests/it/payload.rs index 260d48b3c0a..3af9fb79b21 100644 --- a/crates/rpc/rpc-engine-api/tests/it/payload.rs +++ b/crates/rpc/rpc-engine-api/tests/it/payload.rs @@ -1,15 +1,14 @@ //! Some payload tests +use alloy_rlp::{Decodable, Error as RlpError}; use assert_matches::assert_matches; use reth_interfaces::test_utils::generators::{ self, random_block, random_block_range, random_header, Rng, }; use reth_primitives::{ bytes::{Bytes, BytesMut}, - proofs::{self}, - Block, SealedBlock, TransactionSigned, H256, U256, + proofs, Block, SealedBlock, TransactionSigned, H256, U256, }; -use reth_rlp::{Decodable, DecodeError}; use reth_rpc_types::engine::{ ExecutionPayload, ExecutionPayloadBodyV1, ExecutionPayloadV1, PayloadError, }; @@ -101,10 +100,7 @@ fn payload_validation() { *tx = Bytes::new().into(); }); let payload_with_invalid_txs = try_payload_v1_to_block(payload_with_invalid_txs); - assert_matches!( - payload_with_invalid_txs, - Err(PayloadError::Decode(DecodeError::InputTooShort)) - ); + assert_matches!(payload_with_invalid_txs, Err(PayloadError::Decode(RlpError::InputTooShort))); // Non empty ommers let block_with_ommers = transform_block(block.clone(), |mut b| { diff --git a/crates/rpc/rpc-types-compat/Cargo.toml b/crates/rpc/rpc-types-compat/Cargo.toml index b6f203ef4d1..84e71d6dd6c 100644 --- a/crates/rpc/rpc-types-compat/Cargo.toml +++ b/crates/rpc/rpc-types-compat/Cargo.toml @@ -13,5 +13,5 @@ Compatibility layer for reth-primitives and ethereum RPC types [dependencies] reth-primitives.workspace = true reth-rpc-types.workspace = true -reth-rlp.workspace = true +alloy-rlp.workspace = true diff --git a/crates/rpc/rpc-types-compat/src/block.rs b/crates/rpc/rpc-types-compat/src/block.rs index 6551124d9f7..6bebb6c7058 100644 --- a/crates/rpc/rpc-types-compat/src/block.rs +++ b/crates/rpc/rpc-types-compat/src/block.rs @@ -1,8 +1,8 @@ //! Compatibility functions for rpc `Block` type. use crate::transaction::from_recovered_with_block_context; +use alloy_rlp::Encodable; use reth_primitives::{Block as PrimitiveBlock, Header as PrimitiveHeader, H256, U256}; -use reth_rlp::Encodable; use reth_rpc_types::{Block, BlockError, BlockTransactions, BlockTransactionsKind, Header}; /// Converts the given primitive block into a [Block] response with the given diff --git a/crates/rpc/rpc-types-compat/src/engine/payload.rs b/crates/rpc/rpc-types-compat/src/engine/payload.rs index d5f8e98eabc..beebd486cce 100644 --- a/crates/rpc/rpc-types-compat/src/engine/payload.rs +++ b/crates/rpc/rpc-types-compat/src/engine/payload.rs @@ -1,11 +1,11 @@ //! Standalone Conversion Functions for Handling Different Versions of Execution Payloads in //! Ethereum's Engine +use alloy_rlp::Decodable; use reth_primitives::{ constants::{MAXIMUM_EXTRA_DATA_SIZE, MIN_PROTOCOL_BASE_FEE_U256}, proofs::{self, EMPTY_LIST_HASH}, Block, Header, SealedBlock, TransactionSigned, UintTryTo, Withdrawal, H256, U256, U64, }; -use reth_rlp::Decodable; use reth_rpc_types::engine::{ payload::{ExecutionPayloadBodyV1, ExecutionPayloadFieldV2, ExecutionPayloadInputV2}, ExecutionPayload, ExecutionPayloadV1, ExecutionPayloadV2, ExecutionPayloadV3, PayloadError, diff --git a/crates/rpc/rpc-types/Cargo.toml b/crates/rpc/rpc-types/Cargo.toml index 3dbe236b154..bb387fb6a61 100644 --- a/crates/rpc/rpc-types/Cargo.toml +++ b/crates/rpc/rpc-types/Cargo.toml @@ -13,17 +13,15 @@ Reth RPC types [dependencies] # reth reth-primitives.workspace = true -reth-rlp.workspace = true -# errors -thiserror.workspace = true # misc +alloy-rlp.workspace = true +thiserror.workspace = true itertools.workspace = true serde = { workspace = true, features = ["derive"] } serde_json.workspace = true jsonrpsee-types = { workspace = true, optional = true } - [features] default = ["jsonrpsee-types"] @@ -31,5 +29,3 @@ default = ["jsonrpsee-types"] # misc rand.workspace = true similar-asserts = "1.4" - - diff --git a/crates/rpc/rpc-types/src/eth/block.rs b/crates/rpc/rpc-types/src/eth/block.rs index 5ccd2545ce8..e830641fcb0 100644 --- a/crates/rpc/rpc-types/src/eth/block.rs +++ b/crates/rpc/rpc-types/src/eth/block.rs @@ -56,7 +56,7 @@ pub enum BlockError { InvalidSignature, /// A raw block failed to decode #[error("failed to decode raw block {0}")] - RlpDecodeRawBlock(reth_rlp::DecodeError), + RlpDecodeRawBlock(alloy_rlp::Error), } /// Block representation diff --git a/crates/rpc/rpc-types/src/eth/engine/payload.rs b/crates/rpc/rpc-types/src/eth/engine/payload.rs index c8287ed11aa..d597dc38b6e 100644 --- a/crates/rpc/rpc-types/src/eth/engine/payload.rs +++ b/crates/rpc/rpc-types/src/eth/engine/payload.rs @@ -347,7 +347,7 @@ pub enum PayloadError { InvalidVersionedHashes, /// Encountered decoding error. #[error(transparent)] - Decode(#[from] reth_rlp::DecodeError), + Decode(#[from] alloy_rlp::Error), } impl PayloadError { diff --git a/crates/rpc/rpc-types/src/eth/transaction/typed.rs b/crates/rpc/rpc-types/src/eth/transaction/typed.rs index 149e0f207e2..8b368949321 100644 --- a/crates/rpc/rpc-types/src/eth/transaction/typed.rs +++ b/crates/rpc/rpc-types/src/eth/transaction/typed.rs @@ -3,10 +3,10 @@ //! transaction deserialized from the json input of an RPC call. Depending on what fields are set, //! it can be converted into the container type [`TypedTransactionRequest`]. +use alloy_rlp::{BufMut, Decodable, Encodable, Error as RlpError, RlpDecodable, RlpEncodable}; use reth_primitives::{ AccessList, Address, Bytes, Transaction, TxEip1559, TxEip2930, TxLegacy, U128, U256, U64, }; -use reth_rlp::{BufMut, Decodable, DecodeError, Encodable, RlpDecodable, RlpEncodable}; use serde::{Deserialize, Serialize}; /// Container type for various Ethereum transaction requests @@ -143,7 +143,7 @@ impl Encodable for TransactionKind { } impl Decodable for TransactionKind { - fn decode(buf: &mut &[u8]) -> Result { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { if let Some(&first) = buf.first() { if first == 0x80 { *buf = &buf[1..]; @@ -153,7 +153,7 @@ impl Decodable for TransactionKind { Ok(TransactionKind::Call(addr)) } } else { - Err(DecodeError::InputTooShort) + Err(RlpError::InputTooShort) } } } diff --git a/crates/rpc/rpc-types/src/eth/withdrawal.rs b/crates/rpc/rpc-types/src/eth/withdrawal.rs index 41314ebb5ad..54da7c9a86f 100644 --- a/crates/rpc/rpc-types/src/eth/withdrawal.rs +++ b/crates/rpc/rpc-types/src/eth/withdrawal.rs @@ -1,5 +1,5 @@ +use alloy_rlp::RlpEncodable; use reth_primitives::{constants::GWEI_TO_WEI, serde_helper::u64_hex, Address, U256}; -use reth_rlp::RlpEncodable; use serde::{Deserialize, Serialize}; /// Withdrawal represents a validator withdrawal from the consensus layer. #[derive(Debug, Clone, PartialEq, Eq, Default, Hash, RlpEncodable, Serialize, Deserialize)] diff --git a/crates/rpc/rpc/Cargo.toml b/crates/rpc/rpc/Cargo.toml index cd01da59163..020fdc33e77 100644 --- a/crates/rpc/rpc/Cargo.toml +++ b/crates/rpc/rpc/Cargo.toml @@ -14,7 +14,6 @@ Reth RPC implementation reth-interfaces.workspace = true reth-primitives.workspace = true reth-rpc-api = { path = "../rpc-api" } -reth-rlp.workspace = true reth-rpc-types.workspace = true reth-provider = { workspace = true, features = ["test-utils"] } reth-transaction-pool = { workspace = true, features = ["test-utils"] } @@ -27,6 +26,7 @@ reth-rpc-types-compat.workspace = true lazy_static = "*" # eth +alloy-rlp.workspace = true revm = { workspace = true, features = [ "optional_block_gas_limit", "optional_eip3607", diff --git a/crates/rpc/rpc/src/debug.rs b/crates/rpc/rpc/src/debug.rs index c23ef4a0097..96ba68aa06f 100644 --- a/crates/rpc/rpc/src/debug.rs +++ b/crates/rpc/rpc/src/debug.rs @@ -10,6 +10,7 @@ use crate::{ result::{internal_rpc_err, ToRpcResult}, EthApiSpec, TracingCallGuard, }; +use alloy_rlp::{Decodable, Encodable}; use async_trait::async_trait; use jsonrpsee::core::RpcResult; use reth_primitives::{ @@ -24,7 +25,6 @@ use reth_revm::{ FourByteInspector, TracingInspector, TracingInspectorConfig, }, }; -use reth_rlp::{Decodable, Encodable}; use reth_rpc_api::DebugApiServer; use reth_rpc_types::{ trace::geth::{ diff --git a/crates/stages/Cargo.toml b/crates/stages/Cargo.toml index 6f8ef348233..49f13c2535c 100644 --- a/crates/stages/Cargo.toml +++ b/crates/stages/Cargo.toml @@ -58,10 +58,10 @@ reth-interfaces = { workspace = true, features = ["test-utils"] } reth-downloaders = { path = "../net/downloaders" } reth-eth-wire = { path = "../net/eth-wire" } # TODO(onbjerg): We only need this for [BlockBody] reth-blockchain-tree = { path = "../blockchain-tree" } -reth-rlp.workspace = true reth-revm = { path = "../revm" } reth-trie = { path = "../trie", features = ["test-utils"] } +alloy-rlp.workspace = true itertools.workspace = true tokio = { workspace = true, features = ["rt", "sync", "macros"] } assert_matches.workspace = true diff --git a/crates/stages/src/stages/execution.rs b/crates/stages/src/stages/execution.rs index 6d18436047c..bfca890d5ac 100644 --- a/crates/stages/src/stages/execution.rs +++ b/crates/stages/src/stages/execution.rs @@ -507,6 +507,7 @@ impl ExecutionStageThresholds { mod tests { use super::*; use crate::test_utils::TestTransaction; + use alloy_rlp::Decodable; use assert_matches::assert_matches; use reth_db::{models::AccountBeforeTx, test_utils::create_test_rw_db}; use reth_primitives::{ @@ -515,7 +516,6 @@ mod tests { }; use reth_provider::{AccountReader, BlockWriter, ProviderFactory, ReceiptProvider}; use reth_revm::Factory; - use reth_rlp::Decodable; use std::sync::Arc; fn stage() -> ExecutionStage { diff --git a/crates/stages/src/stages/mod.rs b/crates/stages/src/stages/mod.rs index 4365df676c1..00a82078158 100644 --- a/crates/stages/src/stages/mod.rs +++ b/crates/stages/src/stages/mod.rs @@ -45,6 +45,7 @@ mod tests { test_utils::TestTransaction, ExecInput, }; + use alloy_rlp::Decodable; use reth_db::{ cursor::DbCursorRO, mdbx::{cursor::Cursor, RW}, @@ -62,7 +63,6 @@ mod tests { StorageReader, }; use reth_revm::Factory; - use reth_rlp::Decodable; use std::sync::Arc; #[tokio::test] diff --git a/crates/storage/codecs/derive/src/arbitrary.rs b/crates/storage/codecs/derive/src/arbitrary.rs index 82d35c6e624..0768aa7c70d 100644 --- a/crates/storage/codecs/derive/src/arbitrary.rs +++ b/crates/storage/codecs/derive/src/arbitrary.rs @@ -30,7 +30,7 @@ pub fn maybe_generate_tests(args: TokenStream, ast: &DeriveInput) -> TokenStream } }); } else if arg.to_string() == "rlp" { - traits.push(quote! { use reth_rlp::{Encodable, Decodable}; }); + traits.push(quote! { use alloy_rlp::{Encodable, Decodable}; }); roundtrips.push(quote! { { let mut buf = vec![]; @@ -64,7 +64,7 @@ pub fn maybe_generate_tests(args: TokenStream, ast: &DeriveInput) -> TokenStream // malformed rlp-header check let mut decode_buf = &mut buf.as_slice(); - let mut header = reth_rlp::Header::decode(decode_buf).expect("failed to decode header"); + let mut header = alloy_rlp::Header::decode(decode_buf).expect("failed to decode header"); header.payload_length+=1; let mut b = Vec::with_capacity(decode_buf.len()); header.encode(&mut b); diff --git a/crates/storage/provider/Cargo.toml b/crates/storage/provider/Cargo.toml index f3f918ead7c..027e270e822 100644 --- a/crates/storage/provider/Cargo.toml +++ b/crates/storage/provider/Cargo.toml @@ -32,7 +32,7 @@ pin-project.workspace = true parking_lot.workspace = true # test-utils -reth-rlp = { workspace = true, optional = true } +alloy-rlp = { workspace = true, optional = true } # parallel utils rayon = "1.7" @@ -40,12 +40,13 @@ rayon = "1.7" [dev-dependencies] reth-db = { path = "../db", features = ["test-utils"] } reth-primitives = { workspace = true, features = ["arbitrary", "test-utils"] } -reth-rlp.workspace = true reth-trie = { path = "../../trie", features = ["test-utils"] } reth-interfaces = { workspace = true, features = ["test-utils"] } + +alloy-rlp.workspace = true parking_lot.workspace = true tempfile = "3.3" assert_matches.workspace = true [features] -test-utils = ["reth-rlp"] +test-utils = ["alloy-rlp"] diff --git a/crates/storage/provider/src/providers/database/mod.rs b/crates/storage/provider/src/providers/database/mod.rs index 66701435dd3..b6d27710e67 100644 --- a/crates/storage/provider/src/providers/database/mod.rs +++ b/crates/storage/provider/src/providers/database/mod.rs @@ -406,6 +406,7 @@ impl PruneCheckpointReader for ProviderFactory { mod tests { use super::ProviderFactory; use crate::{BlockHashReader, BlockNumReader, BlockWriter, TransactionsProvider}; + use alloy_rlp::Decodable; use assert_matches::assert_matches; use reth_db::{ tables, @@ -416,7 +417,6 @@ mod tests { use reth_primitives::{ hex_literal::hex, ChainSpecBuilder, PruneMode, PruneModes, SealedBlock, TxNumber, H256, }; - use reth_rlp::Decodable; use std::{ops::RangeInclusive, sync::Arc}; #[test] diff --git a/crates/storage/provider/src/test_utils/blocks.rs b/crates/storage/provider/src/test_utils/blocks.rs index 4f42f78663c..714cbb95e47 100644 --- a/crates/storage/provider/src/test_utils/blocks.rs +++ b/crates/storage/provider/src/test_utils/blocks.rs @@ -1,12 +1,12 @@ //! Dummy blocks and data for tests use crate::{BundleStateWithReceipts, DatabaseProviderRW}; +use alloy_rlp::Decodable; use reth_db::{database::Database, models::StoredBlockBodyIndices, tables}; use reth_primitives::{ b256, hex_literal::hex, Account, Address, BlockNumber, Bytes, Header, Log, Receipt, SealedBlock, SealedBlockWithSenders, StorageEntry, TxType, Withdrawal, H256, U256, }; -use reth_rlp::Decodable; use std::collections::HashMap; /// Assert genesis block diff --git a/crates/transaction-pool/Cargo.toml b/crates/transaction-pool/Cargo.toml index 0ac9379d2af..b99a02bf9ca 100644 --- a/crates/transaction-pool/Cargo.toml +++ b/crates/transaction-pool/Cargo.toml @@ -21,9 +21,10 @@ normal = [ reth-primitives.workspace = true reth-provider.workspace = true reth-interfaces.workspace = true -reth-rlp.workspace = true reth-tasks.workspace = true +alloy-rlp.workspace = true + # async/futures async-trait.workspace = true futures-util.workspace = true diff --git a/crates/transaction-pool/src/blobstore/mod.rs b/crates/transaction-pool/src/blobstore/mod.rs index ce2e875bf91..ead28218222 100644 --- a/crates/transaction-pool/src/blobstore/mod.rs +++ b/crates/transaction-pool/src/blobstore/mod.rs @@ -62,7 +62,7 @@ pub enum BlobStoreError { MissingSidecar(H256), /// Failed to decode the stored blob data. #[error("failed to decode blob data: {0}")] - DecodeError(#[from] reth_rlp::DecodeError), + DecodeError(#[from] alloy_rlp::Error), /// Other implementation specific error. #[error(transparent)] Other(Box), diff --git a/crates/transaction-pool/src/pool/mod.rs b/crates/transaction-pool/src/pool/mod.rs index 95b2c44df47..32a82bcc90b 100644 --- a/crates/transaction-pool/src/pool/mod.rs +++ b/crates/transaction-pool/src/pool/mod.rs @@ -106,8 +106,8 @@ use crate::{ traits::{GetPooledTransactionLimit, TransactionListenerKind}, validate::ValidTransaction, }; +use alloy_rlp::Encodable; pub use listener::{AllTransactionsEvents, TransactionEvents}; -use reth_rlp::Encodable; mod best; mod blob; diff --git a/crates/transaction-pool/src/traits.rs b/crates/transaction-pool/src/traits.rs index a3408b93c3c..4c1a3290829 100644 --- a/crates/transaction-pool/src/traits.rs +++ b/crates/transaction-pool/src/traits.rs @@ -4,6 +4,7 @@ use crate::{ validate::ValidPoolTransaction, AllTransactionsEvents, }; +use alloy_rlp::Encodable; use futures_util::{ready, Stream}; use reth_primitives::{ Address, BlobTransactionSidecar, BlobTransactionValidationError, @@ -12,7 +13,6 @@ use reth_primitives::{ TransactionKind, TransactionSignedEcRecovered, TxEip4844, TxHash, EIP1559_TX_TYPE_ID, EIP4844_TX_TYPE_ID, H256, U256, }; -use reth_rlp::Encodable; use std::{ collections::{HashMap, HashSet}, fmt, diff --git a/crates/trie/Cargo.toml b/crates/trie/Cargo.toml index f3a1e926cb4..85fda73d332 100644 --- a/crates/trie/Cargo.toml +++ b/crates/trie/Cargo.toml @@ -14,9 +14,10 @@ Merkle trie implementation # reth reth-primitives.workspace = true reth-interfaces.workspace = true -reth-rlp.workspace = true reth-db = { path = "../storage/db" } +alloy-rlp.workspace = true + # tokio tokio = { workspace = true, default-features = false, features = ["sync"] } diff --git a/crates/trie/src/account.rs b/crates/trie/src/account.rs index 88307168a03..29ce5d47ccb 100644 --- a/crates/trie/src/account.rs +++ b/crates/trie/src/account.rs @@ -1,5 +1,5 @@ +use alloy_rlp::{RlpDecodable, RlpEncodable}; use reth_primitives::{proofs::EMPTY_ROOT, Account, H256, KECCAK_EMPTY, U256}; -use reth_rlp::{RlpDecodable, RlpEncodable}; /// An Ethereum account as represented in the trie. #[derive(Clone, Copy, Debug, PartialEq, Eq, Default, RlpEncodable, RlpDecodable)] diff --git a/crates/trie/src/proof.rs b/crates/trie/src/proof.rs index fac26e8c5fe..894919234a3 100644 --- a/crates/trie/src/proof.rs +++ b/crates/trie/src/proof.rs @@ -6,6 +6,7 @@ use crate::{ walker::TrieWalker, ProofError, StorageRoot, }; +use alloy_rlp::Encodable; use reth_db::{cursor::DbCursorRO, tables, transaction::DbTx}; use reth_primitives::{ keccak256, @@ -15,7 +16,6 @@ use reth_primitives::{ }, Address, Bytes, H256, }; -use reth_rlp::Encodable; /// A struct for generating merkle proofs. /// diff --git a/crates/trie/src/test_utils.rs b/crates/trie/src/test_utils.rs index 690514acdfe..44dbbd8ea0b 100644 --- a/crates/trie/src/test_utils.rs +++ b/crates/trie/src/test_utils.rs @@ -1,6 +1,6 @@ use crate::account::EthAccount; +use alloy_rlp::{encode_fixed_size, Encodable}; use reth_primitives::{proofs::KeccakHasher, Account, Address, H256, U256}; -use reth_rlp::{encode_fixed_size, Encodable}; /// Re-export of [triehash]. pub use triehash; diff --git a/crates/trie/src/trie.rs b/crates/trie/src/trie.rs index 22a2eda3f80..64419cba1c5 100644 --- a/crates/trie/src/trie.rs +++ b/crates/trie/src/trie.rs @@ -8,6 +8,7 @@ use crate::{ walker::TrieWalker, StateRootError, StorageRootError, }; +use alloy_rlp::Encodable; use reth_db::{tables, transaction::DbTx}; use reth_primitives::{ keccak256, @@ -15,7 +16,6 @@ use reth_primitives::{ trie::{HashBuilder, Nibbles}, Address, BlockNumber, StorageEntry, H256, }; -use reth_rlp::Encodable; use std::{ collections::{HashMap, HashSet}, ops::RangeInclusive, @@ -513,7 +513,7 @@ where } } hash_builder - .add_leaf(storage_key_nibbles, reth_rlp::encode_fixed_size(&value).as_ref()); + .add_leaf(storage_key_nibbles, alloy_rlp::encode_fixed_size(&value).as_ref()); storage = hashed_storage_cursor.next()?; } } @@ -1326,7 +1326,7 @@ mod tests { hashed_storage .upsert(hashed_address, StorageEntry { key: H256::new(key), value }) .unwrap(); - hb.add_leaf(Nibbles::unpack(key), &reth_rlp::encode_fixed_size(&value)); + hb.add_leaf(Nibbles::unpack(key), &alloy_rlp::encode_fixed_size(&value)); } let root = hb.root(); diff --git a/docs/crates/eth-wire.md b/docs/crates/eth-wire.md index 0270668d3f9..dfc85e37dba 100644 --- a/docs/crates/eth-wire.md +++ b/docs/crates/eth-wire.md @@ -65,7 +65,7 @@ These traits are defined as follows: [Crate: crates/rlp](https://github.com/paradigmxyz/reth/tree/1563506aea09049a85e5cc72c2894f3f7a371581/crates/rlp) ```rust, ignore pub trait Decodable: Sized { - fn decode(buf: &mut &[u8]) -> Result; + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result; } pub trait Encodable { fn encode(&self, out: &mut dyn BufMut); @@ -127,7 +127,7 @@ impl Encodable for TransactionSigned { } impl Decodable for TransactionSigned { - fn decode(buf: &mut &[u8]) -> Result { + fn decode(buf: &mut &[u8]) -> alloy_rlp::Result { // Implementation omitted for brevity //... } diff --git a/testing/ef-tests/Cargo.toml b/testing/ef-tests/Cargo.toml index 7145273a931..ea1a48017b3 100644 --- a/testing/ef-tests/Cargo.toml +++ b/testing/ef-tests/Cargo.toml @@ -16,11 +16,12 @@ reth-primitives.workspace = true reth-db = { path = "../../crates/storage/db", features = ["mdbx", "test-utils"] } reth-provider.workspace = true reth-stages = { path = "../../crates/stages" } -reth-rlp.workspace = true reth-interfaces.workspace = true reth-revm = { path = "../../crates/revm" } + +alloy-rlp.workspace = true tokio = "1.28.1" walkdir = "2.3.3" serde = "1.0.163" serde_json.workspace = true -thiserror.workspace = true \ No newline at end of file +thiserror.workspace = true diff --git a/testing/ef-tests/src/cases/blockchain_test.rs b/testing/ef-tests/src/cases/blockchain_test.rs index d240885e724..6b5c10aba0b 100644 --- a/testing/ef-tests/src/cases/blockchain_test.rs +++ b/testing/ef-tests/src/cases/blockchain_test.rs @@ -4,10 +4,10 @@ use crate::{ models::{BlockchainTest, ForkSpec, RootOrState}, Case, Error, Suite, }; +use alloy_rlp::Decodable; use reth_db::test_utils::create_test_rw_db; use reth_primitives::{BlockBody, SealedBlock}; use reth_provider::{BlockWriter, ProviderFactory}; -use reth_rlp::Decodable; use reth_stages::{stages::ExecutionStage, ExecInput, Stage}; use std::{collections::BTreeMap, fs, path::Path, sync::Arc}; diff --git a/testing/ef-tests/src/result.rs b/testing/ef-tests/src/result.rs index 9be3289c153..2709bcab54d 100644 --- a/testing/ef-tests/src/result.rs +++ b/testing/ef-tests/src/result.rs @@ -46,7 +46,7 @@ pub enum Error { RethError(#[from] RethError), /// An error occurred while decoding RLP. #[error("An error occurred deserializing RLP")] - RlpDecodeError(#[from] reth_rlp::DecodeError), + RlpDecodeError(#[from] alloy_rlp::Error), } /// The result of running a test.