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

@ -80,7 +80,7 @@ impl From<Header> for SealedHeader {
base_fee_per_gas: value.base_fee_per_gas.map(|v| v.0.to::<u64>()), base_fee_per_gas: value.base_fee_per_gas.map(|v| v.0.to::<u64>()),
beneficiary: value.coinbase, beneficiary: value.coinbase,
difficulty: value.difficulty.0, difficulty: value.difficulty.0,
extra_data: value.extra_data.0, extra_data: value.extra_data,
gas_limit: value.gas_limit.0.to::<u64>(), gas_limit: value.gas_limit.0.to::<u64>(),
gas_used: value.gas_used.0.to::<u64>(), gas_used: value.gas_used.0.to::<u64>(),
mix_hash: value.mix_hash, mix_hash: value.mix_hash,

View File

@ -48,7 +48,7 @@ impl From<Genesis> for Header {
gas_limit: genesis.gas_limit, gas_limit: genesis.gas_limit,
difficulty: genesis.difficulty, difficulty: genesis.difficulty,
nonce: genesis.nonce, nonce: genesis.nonce,
extra_data: genesis.extra_data.0, extra_data: genesis.extra_data,
state_root: genesis.state_root, state_root: genesis.state_root,
timestamp: genesis.timestamp, timestamp: genesis.timestamp,
mix_hash: genesis.mix_hash, mix_hash: genesis.mix_hash,

View File

@ -143,7 +143,7 @@ impl<Client: HeaderProvider + BlockProvider + StateProvider> EthConsensusEngine<
timestamp: payload.timestamp.as_u64(), timestamp: payload.timestamp.as_u64(),
mix_hash: payload.prev_randao, mix_hash: payload.prev_randao,
base_fee_per_gas: Some(payload.base_fee_per_gas.to::<u64>()), base_fee_per_gas: Some(payload.base_fee_per_gas.to::<u64>()),
extra_data: payload.extra_data.0, extra_data: payload.extra_data,
// Defaults // Defaults
ommers_hash: EMPTY_LIST_HASH, ommers_hash: EMPTY_LIST_HASH,
difficulty: Default::default(), difficulty: Default::default(),
@ -372,7 +372,7 @@ mod tests {
// Valid extra data // Valid extra data
let block_with_valid_extra_data = transform_block(block.clone(), |mut b| { let block_with_valid_extra_data = transform_block(block.clone(), |mut b| {
b.header.extra_data = BytesMut::zeroed(32).freeze(); b.header.extra_data = BytesMut::zeroed(32).freeze().into();
b b
}); });
assert_matches!(engine.try_construct_block(block_with_valid_extra_data.into()), Ok(_)); assert_matches!(engine.try_construct_block(block_with_valid_extra_data.into()), Ok(_));
@ -380,7 +380,7 @@ mod tests {
// Invalid extra data // Invalid extra data
let block_with_invalid_extra_data: Bytes = BytesMut::zeroed(33).freeze(); let block_with_invalid_extra_data: Bytes = BytesMut::zeroed(33).freeze();
let invalid_extra_data_block = transform_block(block.clone(), |mut b| { let invalid_extra_data_block = transform_block(block.clone(), |mut b| {
b.header.extra_data = block_with_invalid_extra_data.clone(); b.header.extra_data = block_with_invalid_extra_data.clone().into();
b b
}); });
assert_matches!( assert_matches!(

View File

@ -194,15 +194,13 @@ mod tests {
let actual_inbound = bandwidth_meter.total_inbound(); let actual_inbound = bandwidth_meter.total_inbound();
assert_eq!( assert_eq!(
actual_inbound, expected_inbound, actual_inbound, expected_inbound,
"Expected {} inbound bytes, but got {}", "Expected {expected_inbound} inbound bytes, but got {actual_inbound}",
expected_inbound, actual_inbound,
); );
let actual_outbound = bandwidth_meter.total_outbound(); let actual_outbound = bandwidth_meter.total_outbound();
assert_eq!( assert_eq!(
actual_outbound, expected_outbound, actual_outbound, expected_outbound,
"Expected {} inbound bytes, but got {}", "Expected {expected_outbound} inbound bytes, but got {actual_outbound}",
expected_outbound, actual_outbound,
); );
} }

View File

@ -55,7 +55,7 @@ impl From<SealedBlock> for ExecutionPayload {
gas_limit: value.gas_limit.into(), gas_limit: value.gas_limit.into(),
gas_used: value.gas_used.into(), gas_used: value.gas_used.into(),
timestamp: value.timestamp.into(), timestamp: value.timestamp.into(),
extra_data: value.extra_data.clone().into(), extra_data: value.extra_data.clone(),
base_fee_per_gas: U256::from(value.base_fee_per_gas.unwrap_or_default()), base_fee_per_gas: U256::from(value.base_fee_per_gas.unwrap_or_default()),
block_hash: value.hash(), block_hash: value.hash(),
transactions, transactions,

View File

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

View File

@ -1,7 +1,7 @@
use crate::{ use crate::{
keccak256, keccak256,
proofs::{EMPTY_LIST_HASH, EMPTY_ROOT}, proofs::{EMPTY_LIST_HASH, EMPTY_ROOT},
BlockHash, BlockNumber, Bloom, H160, H256, U256, BlockHash, BlockNumber, Bloom, Bytes, H160, H256, U256,
}; };
use bytes::{BufMut, BytesMut}; use bytes::{BufMut, BytesMut};
use ethers_core::types::H64; use ethers_core::types::H64;
@ -66,7 +66,7 @@ pub struct Header {
pub base_fee_per_gas: Option<u64>, pub base_fee_per_gas: Option<u64>,
/// An arbitrary byte array containing data relevant to this block. This must be 32 bytes or /// An arbitrary byte array containing data relevant to this block. This must be 32 bytes or
/// fewer; formally Hx. /// fewer; formally Hx.
pub extra_data: bytes::Bytes, pub extra_data: Bytes,
} }
impl Default for Header { impl Default for Header {
@ -355,12 +355,9 @@ impl From<HeadersDirection> for bool {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::{Decodable, Encodable, Header, H256}; use super::{Bytes, Decodable, Encodable, Header, H256};
use crate::{Address, U256}; use crate::{Address, U256};
use ethers_core::{ use ethers_core::utils::hex::{self, FromHex};
types::Bytes,
utils::hex::{self, FromHex},
};
use std::str::FromStr; use std::str::FromStr;
@ -374,7 +371,7 @@ mod tests {
gas_limit: 0x115c_u64, gas_limit: 0x115c_u64,
gas_used: 0x15b3_u64, gas_used: 0x15b3_u64,
timestamp: 0x1a0a_u64, timestamp: 0x1a0a_u64,
extra_data: Bytes::from_str("7788").unwrap().0, extra_data: Bytes::from_str("7788").unwrap(),
ommers_hash: H256::zero(), ommers_hash: H256::zero(),
state_root: H256::zero(), state_root: H256::zero(),
transactions_root: H256::zero(), transactions_root: H256::zero(),
@ -406,7 +403,7 @@ mod tests {
gas_limit: 0x016345785d8a0000_u64, gas_limit: 0x016345785d8a0000_u64,
gas_used: 0x015534_u64, gas_used: 0x015534_u64,
timestamp: 0x079e, timestamp: 0x079e,
extra_data: Bytes::from_str("42").unwrap().0, extra_data: Bytes::from_str("42").unwrap(),
mix_hash: H256::from_str("0000000000000000000000000000000000000000000000000000000000000000").unwrap(), mix_hash: H256::from_str("0000000000000000000000000000000000000000000000000000000000000000").unwrap(),
nonce: 0, nonce: 0,
base_fee_per_gas: Some(0x036b_u64), base_fee_per_gas: Some(0x036b_u64),
@ -424,7 +421,7 @@ mod tests {
gas_limit: 0x115cu64, gas_limit: 0x115cu64,
gas_used: 0x15b3u64, gas_used: 0x15b3u64,
timestamp: 0x1a0au64, timestamp: 0x1a0au64,
extra_data: Bytes::from_str("7788").unwrap().0, extra_data: Bytes::from_str("7788").unwrap(),
ommers_hash: H256::zero(), ommers_hash: H256::zero(),
state_root: H256::zero(), state_root: H256::zero(),
transactions_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 reth_rlp::{Decodable, DecodeError, Encodable};
use serde::{Deserialize, Deserializer, Serializer}; use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::{ use std::{
borrow::Borrow, borrow::Borrow,
clone::Clone, clone::Clone,
@ -11,8 +12,7 @@ use std::{
use thiserror::Error; use thiserror::Error;
/// Wrapper type around Bytes to deserialize/serialize "0x" prefixed ethereum hex strings /// Wrapper type around Bytes to deserialize/serialize "0x" prefixed ethereum hex strings
#[main_codec] #[derive(Clone, Default, PartialEq, Eq, Hash, Ord, PartialOrd, Serialize, Deserialize)]
#[derive(Clone, Default, PartialEq, Eq, Hash, Ord, PartialOrd)]
pub struct Bytes( pub struct Bytes(
#[serde(serialize_with = "serialize_bytes", deserialize_with = "deserialize_bytes")] #[serde(serialize_with = "serialize_bytes", deserialize_with = "deserialize_bytes")]
pub bytes::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 { impl From<bytes::Bytes> for Bytes {
fn from(src: bytes::Bytes) -> Self { fn from(src: bytes::Bytes) -> Self {
Self(src) Self(src)
@ -195,6 +201,39 @@ where
.map_err(|e| serde::de::Error::custom(e.to_string())) .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)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
@ -318,4 +357,17 @@ mod tests {
let wrong_b = bytes::Bytes::from("0123absd"); let wrong_b = bytes::Bytes::from("0123absd");
assert_ne!(wrong_b, b); 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());
});
}
} }