chore(primitives): use reth::Bytes and implements arbitrary (#776)

* clippy

* add arbitrary to reth Bytes

* clean

* add missing dependency
This commit is contained in:
joshieDo
2023-01-09 19:09:18 +08:00
committed by GitHub
parent d98f9fe507
commit 2b5ee2b18d
8 changed files with 76 additions and 26 deletions

View File

@ -45,7 +45,6 @@ serde = "1.0"
serde_with = "2.1.0"
thiserror = "1"
sucds = "0.5.0"
arbitrary = { version = "1.1.7", features = ["derive"], optional = true }
hex = "0.4"
hex-literal = "0.3"
modular-bitfield = "0.11.2"
@ -59,6 +58,10 @@ triehash = "0.8"
plain_hasher = "0.2"
hash-db = "0.15"
# optional
arbitrary = { version = "1.1.7", features = ["derive"], optional = true }
proptest = { version = "1.0", optional = true }
[dev-dependencies]
arbitrary = { version = "1.1.7", features = ["derive"] }
serde_json = "1.0"
@ -75,4 +78,4 @@ secp256k1 = "0.24.2"
[features]
default = []
arbitrary = ["dep:arbitrary", "revm-interpreter/arbitrary"]
arbitrary = ["dep:arbitrary", "dep:proptest", "revm-interpreter/arbitrary"]

View File

@ -1,7 +1,7 @@
use crate::{
keccak256,
proofs::{EMPTY_LIST_HASH, EMPTY_ROOT},
BlockHash, BlockNumber, Bloom, H160, H256, U256,
BlockHash, BlockNumber, Bloom, Bytes, H160, H256, U256,
};
use bytes::{BufMut, BytesMut};
use ethers_core::types::H64;
@ -66,7 +66,7 @@ pub struct Header {
pub base_fee_per_gas: Option<u64>,
/// An arbitrary byte array containing data relevant to this block. This must be 32 bytes or
/// fewer; formally Hx.
pub extra_data: bytes::Bytes,
pub extra_data: Bytes,
}
impl Default for Header {
@ -355,12 +355,9 @@ impl From<HeadersDirection> for bool {
#[cfg(test)]
mod tests {
use super::{Decodable, Encodable, Header, H256};
use super::{Bytes, Decodable, Encodable, Header, H256};
use crate::{Address, U256};
use ethers_core::{
types::Bytes,
utils::hex::{self, FromHex},
};
use ethers_core::utils::hex::{self, FromHex};
use std::str::FromStr;
@ -374,7 +371,7 @@ mod tests {
gas_limit: 0x115c_u64,
gas_used: 0x15b3_u64,
timestamp: 0x1a0a_u64,
extra_data: Bytes::from_str("7788").unwrap().0,
extra_data: Bytes::from_str("7788").unwrap(),
ommers_hash: H256::zero(),
state_root: H256::zero(),
transactions_root: H256::zero(),
@ -406,7 +403,7 @@ mod tests {
gas_limit: 0x016345785d8a0000_u64,
gas_used: 0x015534_u64,
timestamp: 0x079e,
extra_data: Bytes::from_str("42").unwrap().0,
extra_data: Bytes::from_str("42").unwrap(),
mix_hash: H256::from_str("0000000000000000000000000000000000000000000000000000000000000000").unwrap(),
nonce: 0,
base_fee_per_gas: Some(0x036b_u64),
@ -424,7 +421,7 @@ mod tests {
gas_limit: 0x115cu64,
gas_used: 0x15b3u64,
timestamp: 0x1a0au64,
extra_data: Bytes::from_str("7788").unwrap().0,
extra_data: Bytes::from_str("7788").unwrap(),
ommers_hash: H256::zero(),
state_root: H256::zero(),
transactions_root: H256::zero(),

View File

@ -1,6 +1,7 @@
use reth_codecs::{main_codec, Compact};
use bytes::Buf;
use reth_codecs::Compact;
use reth_rlp::{Decodable, DecodeError, Encodable};
use serde::{Deserialize, Deserializer, Serializer};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::{
borrow::Borrow,
clone::Clone,
@ -11,8 +12,7 @@ use std::{
use thiserror::Error;
/// Wrapper type around Bytes to deserialize/serialize "0x" prefixed ethereum hex strings
#[main_codec]
#[derive(Clone, Default, PartialEq, Eq, Hash, Ord, PartialOrd)]
#[derive(Clone, Default, PartialEq, Eq, Hash, Ord, PartialOrd, Serialize, Deserialize)]
pub struct Bytes(
#[serde(serialize_with = "serialize_bytes", deserialize_with = "deserialize_bytes")]
pub bytes::Bytes,
@ -86,6 +86,12 @@ impl<'a> IntoIterator for &'a Bytes {
}
}
impl From<&[u8]> for Bytes {
fn from(src: &[u8]) -> Self {
Self(bytes::Bytes::copy_from_slice(src))
}
}
impl From<bytes::Bytes> for Bytes {
fn from(src: bytes::Bytes) -> Self {
Self(src)
@ -195,6 +201,39 @@ where
.map_err(|e| serde::de::Error::custom(e.to_string()))
}
impl Compact for Bytes {
fn to_compact(self, buf: &mut impl bytes::BufMut) -> usize {
let len = self.len();
buf.put(self.0);
len
}
fn from_compact(mut buf: &[u8], len: usize) -> (Self, &[u8]) {
(buf.copy_to_bytes(len).into(), buf)
}
}
#[cfg(any(test, feature = "arbitrary"))]
use proptest::strategy::Strategy;
#[cfg(any(test, feature = "arbitrary"))]
impl proptest::prelude::Arbitrary for Bytes {
type Parameters = proptest::arbitrary::ParamsFor<u8>;
type Strategy = proptest::prelude::BoxedStrategy<Bytes>;
fn arbitrary_with(args: Self::Parameters) -> Self::Strategy {
proptest::collection::vec(proptest::arbitrary::any_with::<u8>(args), 0..1000)
.prop_map(move |vec| bytes::Bytes::from(vec).into())
.boxed()
}
}
#[cfg(any(test, feature = "arbitrary"))]
impl<'a> arbitrary::Arbitrary<'a> for Bytes {
fn arbitrary(u: &mut arbitrary::Unstructured<'a>) -> arbitrary::Result<Self> {
let size = u.int_in_range(0..=1000)?;
Ok(Self(bytes::Bytes::copy_from_slice(u.bytes(size)?)))
}
}
#[cfg(test)]
mod tests {
use super::*;
@ -318,4 +357,17 @@ mod tests {
let wrong_b = bytes::Bytes::from("0123absd");
assert_ne!(wrong_b, b);
}
#[test]
fn arbitrary() {
proptest::proptest!(|(bytes: Bytes)| {
let mut buf = vec![];
bytes.clone().to_compact(&mut buf);
let (decoded, remaining_buf) = Bytes::from_compact(&buf, buf.len());
assert!(bytes == decoded);
assert!(remaining_buf.is_empty());
});
}
}