mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
reth-primitives: Allow feature gating zstd for non default feature set (#7296)
This commit is contained in:
@ -49,7 +49,7 @@ serde_json.workspace = true
|
||||
sha2 = { version = "0.10.7", optional = true }
|
||||
tempfile = { workspace = true, optional = true }
|
||||
thiserror.workspace = true
|
||||
zstd = { version = "0.12", features = ["experimental"] }
|
||||
zstd = { version = "0.12", features = ["experimental"], optional = true }
|
||||
roaring = "0.10.2"
|
||||
cfg-if = "1.0.0"
|
||||
|
||||
@ -90,7 +90,7 @@ pprof = { workspace = true, features = ["flamegraph", "frame-pointer", "criterio
|
||||
secp256k1.workspace = true
|
||||
|
||||
[features]
|
||||
default = ["c-kzg"]
|
||||
default = ["c-kzg", "zstd-codec"]
|
||||
asm-keccak = ["alloy-primitives/asm-keccak"]
|
||||
arbitrary = [
|
||||
"revm-primitives/arbitrary",
|
||||
@ -102,8 +102,12 @@ arbitrary = [
|
||||
"dep:arbitrary",
|
||||
"dep:proptest",
|
||||
"dep:proptest-derive",
|
||||
"zstd-codec"
|
||||
]
|
||||
c-kzg = ["dep:c-kzg", "revm/c-kzg", "revm-primitives/c-kzg", "dep:sha2", "dep:tempfile"]
|
||||
zstd-codec = [
|
||||
"dep:zstd"
|
||||
]
|
||||
clap = ["dep:clap"]
|
||||
optimism = [
|
||||
"reth-codecs/optimism",
|
||||
|
||||
@ -21,6 +21,7 @@ mod account;
|
||||
pub mod basefee;
|
||||
mod block;
|
||||
mod chain;
|
||||
#[cfg(feature = "zstd-codec")]
|
||||
mod compression;
|
||||
pub mod constants;
|
||||
pub mod eip4844;
|
||||
@ -58,6 +59,7 @@ pub use chain::{
|
||||
ChainSpecBuilder, DisplayHardforks, ForkBaseFeeParams, ForkCondition, ForkTimestamps,
|
||||
NamedChain, DEV, GOERLI, HOLESKY, MAINNET, SEPOLIA,
|
||||
};
|
||||
#[cfg(feature = "zstd-codec")]
|
||||
pub use compression::*;
|
||||
pub use constants::{
|
||||
DEV_GENESIS_HASH, EMPTY_OMMER_ROOT_HASH, GOERLI_GENESIS_HASH, HOLESKY_GENESIS_HASH,
|
||||
|
||||
@ -1,19 +1,21 @@
|
||||
use crate::{
|
||||
compression::{RECEIPT_COMPRESSOR, RECEIPT_DECOMPRESSOR},
|
||||
logs_bloom, Bloom, Bytes, Log, PruneSegmentError, TxType, B256,
|
||||
};
|
||||
#[cfg(feature = "zstd-codec")]
|
||||
use crate::compression::{RECEIPT_COMPRESSOR, RECEIPT_DECOMPRESSOR};
|
||||
use crate::{logs_bloom, Bloom, Bytes, Log, PruneSegmentError, TxType, B256};
|
||||
use alloy_rlp::{length_of_length, Decodable, Encodable};
|
||||
use bytes::{Buf, BufMut};
|
||||
#[cfg(any(test, feature = "arbitrary"))]
|
||||
use proptest::strategy::Strategy;
|
||||
use reth_codecs::{add_arbitrary_tests, main_codec, Compact, CompactZstd};
|
||||
#[cfg(feature = "zstd-codec")]
|
||||
use reth_codecs::CompactZstd;
|
||||
use reth_codecs::{add_arbitrary_tests, main_codec, Compact};
|
||||
use std::{
|
||||
cmp::Ordering,
|
||||
ops::{Deref, DerefMut},
|
||||
};
|
||||
|
||||
/// Receipt containing result of transaction execution.
|
||||
#[main_codec(no_arbitrary, zstd)]
|
||||
#[cfg_attr(feature = "zstd-codec", main_codec(no_arbitrary, zstd))]
|
||||
#[cfg_attr(not(feature = "zstd-codec"), main_codec(no_arbitrary))]
|
||||
#[add_arbitrary_tests]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Default)]
|
||||
pub struct Receipt {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
compression::{TRANSACTION_COMPRESSOR, TRANSACTION_DECOMPRESSOR},
|
||||
keccak256, Address, BlockHashOrNumber, Bytes, TxHash, B256, U256,
|
||||
};
|
||||
#[cfg(any(feature = "arbitrary", feature = "zstd-codec"))]
|
||||
use crate::compression::{TRANSACTION_COMPRESSOR, TRANSACTION_DECOMPRESSOR};
|
||||
use crate::{keccak256, Address, BlockHashOrNumber, Bytes, TxHash, B256, U256};
|
||||
|
||||
use alloy_rlp::{
|
||||
Decodable, Encodable, Error as RlpError, Header, EMPTY_LIST_CODE, EMPTY_STRING_CODE,
|
||||
};
|
||||
@ -52,6 +52,7 @@ mod variant;
|
||||
|
||||
#[cfg(feature = "optimism")]
|
||||
mod optimism;
|
||||
|
||||
#[cfg(feature = "optimism")]
|
||||
pub use optimism::TxDeposit;
|
||||
#[cfg(feature = "optimism")]
|
||||
@ -884,6 +885,7 @@ impl TransactionSignedNoHash {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "zstd-codec")]
|
||||
impl Compact for TransactionSignedNoHash {
|
||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
||||
where
|
||||
@ -946,6 +948,64 @@ impl Compact for TransactionSignedNoHash {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "zstd-codec"))]
|
||||
impl Compact for TransactionSignedNoHash {
|
||||
fn to_compact<B>(self, buf: &mut B) -> usize
|
||||
where
|
||||
B: bytes::BufMut + AsMut<[u8]>,
|
||||
{
|
||||
to_compact_ztd_unaware(self, buf)
|
||||
}
|
||||
|
||||
fn from_compact(mut buf: &[u8], _len: usize) -> (Self, &[u8]) {
|
||||
from_compact_zstd_unaware(buf, _len)
|
||||
}
|
||||
}
|
||||
|
||||
// Allowing dead code, as this function is extracted from behind feature, so it can be tested
|
||||
#[allow(dead_code)]
|
||||
fn to_compact_ztd_unaware<B>(transaction: TransactionSignedNoHash, buf: &mut B) -> usize
|
||||
where
|
||||
B: bytes::BufMut + AsMut<[u8]>,
|
||||
{
|
||||
let start = buf.as_mut().len();
|
||||
|
||||
// Placeholder for bitflags.
|
||||
// The first byte uses 4 bits as flags: IsCompressed[1bit], TxType[2bits], Signature[1bit]
|
||||
buf.put_u8(0);
|
||||
|
||||
let sig_bit = transaction.signature.to_compact(buf) as u8;
|
||||
let zstd_bit = false;
|
||||
let tx_bits = transaction.transaction.to_compact(buf) as u8;
|
||||
|
||||
// Replace bitflags with the actual values
|
||||
buf.as_mut()[start] = sig_bit | (tx_bits << 1) | ((zstd_bit as u8) << 3);
|
||||
|
||||
buf.as_mut().len() - start
|
||||
}
|
||||
|
||||
// Allowing dead code, as this function is extracted from behind feature, so it can be tested
|
||||
#[allow(dead_code)]
|
||||
fn from_compact_zstd_unaware(mut buf: &[u8], _len: usize) -> (TransactionSignedNoHash, &[u8]) {
|
||||
// The first byte uses 4 bits as flags: IsCompressed[1], TxType[2], Signature[1]
|
||||
let bitflags = buf.get_u8() as usize;
|
||||
|
||||
let sig_bit = bitflags & 1;
|
||||
let (signature, buf) = Signature::from_compact(buf, sig_bit);
|
||||
|
||||
let zstd_bit = bitflags >> 3;
|
||||
if zstd_bit != 0 {
|
||||
panic!(
|
||||
"zstd-codec feature is not enabled, cannot decode `TransactionSignedNoHash` with zstd flag"
|
||||
)
|
||||
}
|
||||
|
||||
let transaction_type = bitflags >> 1;
|
||||
let (transaction, buf) = Transaction::from_compact(buf, transaction_type);
|
||||
|
||||
(TransactionSignedNoHash { signature, transaction }, buf)
|
||||
}
|
||||
|
||||
impl From<TransactionSignedNoHash> for TransactionSigned {
|
||||
fn from(tx: TransactionSignedNoHash) -> Self {
|
||||
tx.with_hash()
|
||||
@ -1405,7 +1465,7 @@ impl Decodable for TransactionSigned {
|
||||
/// header if the first byte is less than `0xf7`.
|
||||
fn decode(buf: &mut &[u8]) -> alloy_rlp::Result<Self> {
|
||||
if buf.is_empty() {
|
||||
return Err(RlpError::InputTooShort)
|
||||
return Err(RlpError::InputTooShort);
|
||||
}
|
||||
|
||||
// decode header
|
||||
@ -1602,17 +1662,18 @@ mod tests {
|
||||
use crate::{
|
||||
hex, sign_message,
|
||||
transaction::{
|
||||
signature::Signature, TransactionKind, TxEip1559, TxLegacy,
|
||||
MIN_LENGTH_EIP1559_TX_ENCODED, MIN_LENGTH_EIP2930_TX_ENCODED,
|
||||
MIN_LENGTH_EIP4844_TX_ENCODED, MIN_LENGTH_LEGACY_TX_ENCODED,
|
||||
PARALLEL_SENDER_RECOVERY_THRESHOLD,
|
||||
from_compact_zstd_unaware, signature::Signature, to_compact_ztd_unaware,
|
||||
TransactionKind, TxEip1559, TxLegacy, MIN_LENGTH_EIP1559_TX_ENCODED,
|
||||
MIN_LENGTH_EIP2930_TX_ENCODED, MIN_LENGTH_EIP4844_TX_ENCODED,
|
||||
MIN_LENGTH_LEGACY_TX_ENCODED, PARALLEL_SENDER_RECOVERY_THRESHOLD,
|
||||
},
|
||||
Address, Bytes, Transaction, TransactionSigned, TransactionSignedEcRecovered, TxEip2930,
|
||||
TxEip4844, B256, U256,
|
||||
Address, Bytes, Transaction, TransactionSigned, TransactionSignedEcRecovered,
|
||||
TransactionSignedNoHash, TxEip2930, TxEip4844, B256, U256,
|
||||
};
|
||||
use alloy_primitives::{address, b256, bytes};
|
||||
use alloy_rlp::{Decodable, Encodable, Error as RlpError};
|
||||
use bytes::BytesMut;
|
||||
use reth_codecs::Compact;
|
||||
use secp256k1::{KeyPair, Secp256k1};
|
||||
use std::str::FromStr;
|
||||
|
||||
@ -1684,7 +1745,7 @@ mod tests {
|
||||
b256!("0152d8e24762ff22b1cfd9f8c0683786a7ca63ba49973818b3d1e9512cd2cec4"),
|
||||
b256!("013b98c6c83e066d5b14af2b85199e3d4fc7d1e778dd53130d180f5077e2d1c7"),
|
||||
b256!("01148b495d6e859114e670ca54fb6e2657f0cbae5b08063605093a4b3dc9f8f1"),
|
||||
b256!("011ac212f13c5dff2b2c6b600a79635103d6f580a4221079951181b25c7e6549")
|
||||
b256!("011ac212f13c5dff2b2c6b600a79635103d6f580a4221079951181b25c7e6549"),
|
||||
])
|
||||
);
|
||||
}
|
||||
@ -1837,7 +1898,7 @@ mod tests {
|
||||
let hash: B256 =
|
||||
hex!("559fb34c4a7f115db26cbf8505389475caaab3df45f5c7a0faa4abfa3835306c").into();
|
||||
let signer: Address = hex!("641c5d790f862a58ec7abcfd644c0442e9c201b3").into();
|
||||
let raw =hex!("f88b8212b085028fa6ae00830f424094aad593da0c8116ef7d2d594dd6a63241bccfc26c80a48318b64b000000000000000000000000641c5d790f862a58ec7abcfd644c0442e9c201b32aa0a6ef9e170bca5ffb7ac05433b13b7043de667fbb0b4a5e45d3b54fb2d6efcc63a0037ec2c05c3d60c5f5f78244ce0a3859e3a18a36c61efb061b383507d3ce19d2");
|
||||
let raw = hex!("f88b8212b085028fa6ae00830f424094aad593da0c8116ef7d2d594dd6a63241bccfc26c80a48318b64b000000000000000000000000641c5d790f862a58ec7abcfd644c0442e9c201b32aa0a6ef9e170bca5ffb7ac05433b13b7043de667fbb0b4a5e45d3b54fb2d6efcc63a0037ec2c05c3d60c5f5f78244ce0a3859e3a18a36c61efb061b383507d3ce19d2");
|
||||
|
||||
let mut pointer = raw.as_ref();
|
||||
let tx = TransactionSigned::decode(&mut pointer).unwrap();
|
||||
@ -2036,4 +2097,96 @@ mod tests {
|
||||
|
||||
TransactionSigned::decode(&mut &encoded[..]).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn transaction_signed_no_hash_zstd_codec() {
|
||||
// will use same signature everywhere.
|
||||
// We don't need signature to match tx, just decoded to the same signature
|
||||
let signature = Signature {
|
||||
odd_y_parity: false,
|
||||
r: U256::from_str("0xeb96ca19e8a77102767a41fc85a36afd5c61ccb09911cec5d3e86e193d9c5ae")
|
||||
.unwrap(),
|
||||
s: U256::from_str("0x3a456401896b1b6055311536bf00a718568c744d8c1f9df59879e8350220ca18")
|
||||
.unwrap(),
|
||||
};
|
||||
|
||||
let inputs: Vec<Vec<u8>> = vec![
|
||||
vec![],
|
||||
vec![0],
|
||||
vec![255],
|
||||
vec![1u8; 31],
|
||||
vec![255u8; 31],
|
||||
vec![1u8; 32],
|
||||
vec![255u8; 32],
|
||||
vec![1u8; 64],
|
||||
vec![255u8; 64],
|
||||
];
|
||||
|
||||
for input in inputs {
|
||||
let transaction = Transaction::Legacy(TxLegacy {
|
||||
chain_id: Some(4u64),
|
||||
nonce: 2,
|
||||
gas_price: 1000000000,
|
||||
gas_limit: 100000,
|
||||
to: TransactionKind::Call(
|
||||
Address::from_str("d3e8763675e4c425df46cc3b5c0f6cbdac396046").unwrap(),
|
||||
),
|
||||
value: U256::from(1000000000000000u64),
|
||||
input: Bytes::from(input),
|
||||
});
|
||||
|
||||
let tx_signed_no_hash = TransactionSignedNoHash { signature, transaction };
|
||||
test_transaction_signed_to_from_compact(tx_signed_no_hash);
|
||||
}
|
||||
}
|
||||
|
||||
fn test_transaction_signed_to_from_compact(tx_signed_no_hash: TransactionSignedNoHash) {
|
||||
// zstd aware `to_compact`
|
||||
let mut buff: Vec<u8> = Vec::new();
|
||||
let written_bytes = tx_signed_no_hash.clone().to_compact(&mut buff);
|
||||
let (decoded, _) = TransactionSignedNoHash::from_compact(&buff, written_bytes);
|
||||
assert_eq!(tx_signed_no_hash, decoded);
|
||||
|
||||
// zstd unaware `to_compact`/`from_compact`
|
||||
let mut buff: Vec<u8> = Vec::new();
|
||||
let written_bytes = to_compact_ztd_unaware(tx_signed_no_hash.clone(), &mut buff);
|
||||
let (decoded_no_zstd, _something) = from_compact_zstd_unaware(&buff, written_bytes);
|
||||
assert_eq!(tx_signed_no_hash, decoded_no_zstd);
|
||||
|
||||
// zstd unaware `to_compact`, but decode with zstd awareness
|
||||
let mut buff: Vec<u8> = Vec::new();
|
||||
let written_bytes = to_compact_ztd_unaware(tx_signed_no_hash.clone(), &mut buff);
|
||||
let (decoded, _) = TransactionSignedNoHash::from_compact(&buff, written_bytes);
|
||||
assert_eq!(tx_signed_no_hash, decoded);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(
|
||||
expected = "zstd-codec feature is not enabled, cannot decode `TransactionSignedNoHash` with zstd flag"
|
||||
)]
|
||||
fn transaction_signed_zstd_encoded_no_zstd_decode() {
|
||||
let signature = Signature {
|
||||
odd_y_parity: false,
|
||||
r: U256::from_str("0xeb96ca19e8a77102767a41fc85a36afd5c61ccb09911cec5d3e86e193d9c5ae")
|
||||
.unwrap(),
|
||||
s: U256::from_str("0x3a456401896b1b6055311536bf00a718568c744d8c1f9df59879e8350220ca18")
|
||||
.unwrap(),
|
||||
};
|
||||
let transaction = Transaction::Legacy(TxLegacy {
|
||||
chain_id: Some(4u64),
|
||||
nonce: 2,
|
||||
gas_price: 1000000000,
|
||||
gas_limit: 100000,
|
||||
to: TransactionKind::Call(
|
||||
Address::from_str("d3e8763675e4c425df46cc3b5c0f6cbdac396046").unwrap(),
|
||||
),
|
||||
value: U256::from(1000000000000000u64),
|
||||
input: Bytes::from(vec![3u8; 64]),
|
||||
});
|
||||
let tx_signed_no_hash = TransactionSignedNoHash { signature, transaction };
|
||||
|
||||
let mut buff: Vec<u8> = Vec::new();
|
||||
let written_bytes = tx_signed_no_hash.to_compact(&mut buff);
|
||||
from_compact_zstd_unaware(&buff, written_bytes);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user