mirror of
https://github.com/hl-archive-node/nanoreth.git
synced 2025-12-06 10:59:55 +00:00
chore: move some tests to engine crate (#3968)
This commit is contained in:
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -5779,6 +5779,7 @@ dependencies = [
|
||||
"reth-payload-builder",
|
||||
"reth-primitives",
|
||||
"reth-provider",
|
||||
"reth-rlp",
|
||||
"reth-rpc-api",
|
||||
"reth-rpc-types",
|
||||
"reth-tasks",
|
||||
@ -5791,10 +5792,8 @@ dependencies = [
|
||||
name = "reth-rpc-types"
|
||||
version = "0.1.0-alpha.4"
|
||||
dependencies = [
|
||||
"assert_matches",
|
||||
"jsonrpsee-types",
|
||||
"rand 0.8.5",
|
||||
"reth-interfaces",
|
||||
"reth-primitives",
|
||||
"reth-rlp",
|
||||
"serde",
|
||||
|
||||
@ -30,6 +30,7 @@ jsonrpsee-core = "0.18"
|
||||
tracing.workspace = true
|
||||
|
||||
[dev-dependencies]
|
||||
reth-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"] }
|
||||
|
||||
@ -29,3 +29,10 @@ pub use message::EngineApiMessageVersion;
|
||||
|
||||
// re-export server trait for convenience
|
||||
pub use reth_rpc_api::EngineApiServer;
|
||||
|
||||
#[cfg(test)]
|
||||
#[allow(unused_imports)]
|
||||
mod tests {
|
||||
// silence unused import warning
|
||||
use reth_rlp as _;
|
||||
}
|
||||
|
||||
3
crates/rpc/rpc-engine-api/tests/it/main.rs
Normal file
3
crates/rpc/rpc-engine-api/tests/it/main.rs
Normal file
@ -0,0 +1,3 @@
|
||||
mod payload;
|
||||
|
||||
fn main() {}
|
||||
127
crates/rpc/rpc-engine-api/tests/it/payload.rs
Normal file
127
crates/rpc/rpc-engine-api/tests/it/payload.rs
Normal file
@ -0,0 +1,127 @@
|
||||
//! Some payload tests
|
||||
|
||||
use assert_matches::assert_matches;
|
||||
use reth_interfaces::test_utils::generators::{
|
||||
self, random_block, random_block_range, random_header,
|
||||
};
|
||||
use reth_primitives::{
|
||||
bytes::{Bytes, BytesMut},
|
||||
proofs::{self},
|
||||
Block, SealedBlock, TransactionSigned, H256, U256,
|
||||
};
|
||||
use reth_rlp::{Decodable, DecodeError};
|
||||
use reth_rpc_types::engine::{ExecutionPayload, ExecutionPayloadBodyV1, PayloadError};
|
||||
|
||||
fn transform_block<F: FnOnce(Block) -> Block>(src: SealedBlock, f: F) -> ExecutionPayload {
|
||||
let unsealed = src.unseal();
|
||||
let mut transformed: Block = f(unsealed);
|
||||
// Recalculate roots
|
||||
transformed.header.transactions_root = proofs::calculate_transaction_root(&transformed.body);
|
||||
transformed.header.ommers_hash = proofs::calculate_ommers_root(&transformed.ommers);
|
||||
SealedBlock {
|
||||
header: transformed.header.seal_slow(),
|
||||
body: transformed.body,
|
||||
ommers: transformed.ommers,
|
||||
withdrawals: transformed.withdrawals,
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn payload_body_roundtrip() {
|
||||
let mut rng = generators::rng();
|
||||
for block in random_block_range(&mut rng, 0..=99, H256::default(), 0..2) {
|
||||
let unsealed = block.clone().unseal();
|
||||
let payload_body: ExecutionPayloadBodyV1 = unsealed.into();
|
||||
|
||||
assert_eq!(
|
||||
Ok(block.body),
|
||||
payload_body
|
||||
.transactions
|
||||
.iter()
|
||||
.map(|x| TransactionSigned::decode(&mut &x[..]))
|
||||
.collect::<Result<Vec<_>, _>>(),
|
||||
);
|
||||
|
||||
assert_eq!(block.withdrawals, payload_body.withdrawals);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn payload_validation() {
|
||||
let mut rng = generators::rng();
|
||||
let block = random_block(&mut rng, 100, Some(H256::random()), Some(3), Some(0));
|
||||
|
||||
// Valid extra data
|
||||
let block_with_valid_extra_data = transform_block(block.clone(), |mut b| {
|
||||
b.header.extra_data = BytesMut::zeroed(32).freeze().into();
|
||||
b
|
||||
});
|
||||
assert_matches!(TryInto::<SealedBlock>::try_into(block_with_valid_extra_data), Ok(_));
|
||||
|
||||
// Invalid extra data
|
||||
let block_with_invalid_extra_data: Bytes = BytesMut::zeroed(33).freeze();
|
||||
let invalid_extra_data_block = transform_block(block.clone(), |mut b| {
|
||||
b.header.extra_data = block_with_invalid_extra_data.clone().into();
|
||||
b
|
||||
});
|
||||
assert_matches!(
|
||||
TryInto::<SealedBlock>::try_into(invalid_extra_data_block),
|
||||
Err(PayloadError::ExtraData(data)) if data == block_with_invalid_extra_data
|
||||
);
|
||||
|
||||
// Zero base fee
|
||||
let block_with_zero_base_fee = transform_block(block.clone(), |mut b| {
|
||||
b.header.base_fee_per_gas = Some(0);
|
||||
b
|
||||
});
|
||||
assert_matches!(
|
||||
TryInto::<SealedBlock>::try_into(block_with_zero_base_fee),
|
||||
Err(PayloadError::BaseFee(val)) if val == U256::ZERO
|
||||
);
|
||||
|
||||
// Invalid encoded transactions
|
||||
let mut payload_with_invalid_txs: ExecutionPayload = block.clone().into();
|
||||
payload_with_invalid_txs.transactions.iter_mut().for_each(|tx| {
|
||||
*tx = Bytes::new().into();
|
||||
});
|
||||
assert_matches!(
|
||||
TryInto::<SealedBlock>::try_into(payload_with_invalid_txs),
|
||||
Err(PayloadError::Decode(DecodeError::InputTooShort))
|
||||
);
|
||||
|
||||
// Non empty ommers
|
||||
let block_with_ommers = transform_block(block.clone(), |mut b| {
|
||||
b.ommers.push(random_header(&mut rng, 100, None).unseal());
|
||||
b
|
||||
});
|
||||
assert_matches!(
|
||||
TryInto::<SealedBlock>::try_into(block_with_ommers.clone()),
|
||||
Err(PayloadError::BlockHash { consensus, .. })
|
||||
if consensus == block_with_ommers.block_hash
|
||||
);
|
||||
|
||||
// None zero difficulty
|
||||
let block_with_difficulty = transform_block(block.clone(), |mut b| {
|
||||
b.header.difficulty = U256::from(1);
|
||||
b
|
||||
});
|
||||
assert_matches!(
|
||||
TryInto::<SealedBlock>::try_into(block_with_difficulty.clone()),
|
||||
Err(PayloadError::BlockHash { consensus, .. }) if consensus == block_with_difficulty.block_hash
|
||||
);
|
||||
|
||||
// None zero nonce
|
||||
let block_with_nonce = transform_block(block.clone(), |mut b| {
|
||||
b.header.nonce = 1;
|
||||
b
|
||||
});
|
||||
assert_matches!(
|
||||
TryInto::<SealedBlock>::try_into(block_with_nonce.clone()),
|
||||
Err(PayloadError::BlockHash { consensus, .. }) if consensus == block_with_nonce.block_hash
|
||||
);
|
||||
|
||||
// Valid block
|
||||
let valid_block = block;
|
||||
assert_matches!(TryInto::<SealedBlock>::try_into(valid_block), Ok(_));
|
||||
}
|
||||
@ -24,10 +24,6 @@ serde_json.workspace = true
|
||||
jsonrpsee-types = { version = "0.18" }
|
||||
|
||||
[dev-dependencies]
|
||||
# reth
|
||||
reth-interfaces = { workspace = true, features = ["test-utils"] }
|
||||
|
||||
# misc
|
||||
rand.workspace = true
|
||||
assert_matches = "1.5"
|
||||
similar-asserts = "1.4"
|
||||
|
||||
@ -446,130 +446,6 @@ pub enum PayloadValidationError {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use assert_matches::assert_matches;
|
||||
use reth_interfaces::test_utils::generators::{
|
||||
self, random_block, random_block_range, random_header,
|
||||
};
|
||||
use reth_primitives::{
|
||||
bytes::{Bytes, BytesMut},
|
||||
TransactionSigned, H256,
|
||||
};
|
||||
use reth_rlp::{Decodable, DecodeError};
|
||||
|
||||
fn transform_block<F: FnOnce(Block) -> Block>(src: SealedBlock, f: F) -> ExecutionPayload {
|
||||
let unsealed = src.unseal();
|
||||
let mut transformed: Block = f(unsealed);
|
||||
// Recalculate roots
|
||||
transformed.header.transactions_root =
|
||||
proofs::calculate_transaction_root(&transformed.body);
|
||||
transformed.header.ommers_hash = proofs::calculate_ommers_root(&transformed.ommers);
|
||||
SealedBlock {
|
||||
header: transformed.header.seal_slow(),
|
||||
body: transformed.body,
|
||||
ommers: transformed.ommers,
|
||||
withdrawals: transformed.withdrawals,
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn payload_body_roundtrip() {
|
||||
let mut rng = generators::rng();
|
||||
for block in random_block_range(&mut rng, 0..=99, H256::default(), 0..2) {
|
||||
let unsealed = block.clone().unseal();
|
||||
let payload_body: ExecutionPayloadBodyV1 = unsealed.into();
|
||||
|
||||
assert_eq!(
|
||||
Ok(block.body),
|
||||
payload_body
|
||||
.transactions
|
||||
.iter()
|
||||
.map(|x| TransactionSigned::decode(&mut &x[..]))
|
||||
.collect::<Result<Vec<_>, _>>(),
|
||||
);
|
||||
|
||||
assert_eq!(block.withdrawals, payload_body.withdrawals);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn payload_validation() {
|
||||
let mut rng = generators::rng();
|
||||
let block = random_block(&mut rng, 100, Some(H256::random()), Some(3), Some(0));
|
||||
|
||||
// Valid extra data
|
||||
let block_with_valid_extra_data = transform_block(block.clone(), |mut b| {
|
||||
b.header.extra_data = BytesMut::zeroed(32).freeze().into();
|
||||
b
|
||||
});
|
||||
assert_matches!(TryInto::<SealedBlock>::try_into(block_with_valid_extra_data), Ok(_));
|
||||
|
||||
// Invalid extra data
|
||||
let block_with_invalid_extra_data: Bytes = BytesMut::zeroed(33).freeze();
|
||||
let invalid_extra_data_block = transform_block(block.clone(), |mut b| {
|
||||
b.header.extra_data = block_with_invalid_extra_data.clone().into();
|
||||
b
|
||||
});
|
||||
assert_matches!(
|
||||
TryInto::<SealedBlock>::try_into(invalid_extra_data_block),
|
||||
Err(PayloadError::ExtraData(data)) if data == block_with_invalid_extra_data
|
||||
);
|
||||
|
||||
// Zero base fee
|
||||
let block_with_zero_base_fee = transform_block(block.clone(), |mut b| {
|
||||
b.header.base_fee_per_gas = Some(0);
|
||||
b
|
||||
});
|
||||
assert_matches!(
|
||||
TryInto::<SealedBlock>::try_into(block_with_zero_base_fee),
|
||||
Err(PayloadError::BaseFee(val)) if val == U256::ZERO
|
||||
);
|
||||
|
||||
// Invalid encoded transactions
|
||||
let mut payload_with_invalid_txs: ExecutionPayload = block.clone().into();
|
||||
payload_with_invalid_txs.transactions.iter_mut().for_each(|tx| {
|
||||
*tx = Bytes::new().into();
|
||||
});
|
||||
assert_matches!(
|
||||
TryInto::<SealedBlock>::try_into(payload_with_invalid_txs),
|
||||
Err(PayloadError::Decode(DecodeError::InputTooShort))
|
||||
);
|
||||
|
||||
// Non empty ommers
|
||||
let block_with_ommers = transform_block(block.clone(), |mut b| {
|
||||
b.ommers.push(random_header(&mut rng, 100, None).unseal());
|
||||
b
|
||||
});
|
||||
assert_matches!(
|
||||
TryInto::<SealedBlock>::try_into(block_with_ommers.clone()),
|
||||
Err(PayloadError::BlockHash { consensus, .. })
|
||||
if consensus == block_with_ommers.block_hash
|
||||
);
|
||||
|
||||
// None zero difficulty
|
||||
let block_with_difficulty = transform_block(block.clone(), |mut b| {
|
||||
b.header.difficulty = U256::from(1);
|
||||
b
|
||||
});
|
||||
assert_matches!(
|
||||
TryInto::<SealedBlock>::try_into(block_with_difficulty.clone()),
|
||||
Err(PayloadError::BlockHash { consensus, .. }) if consensus == block_with_difficulty.block_hash
|
||||
);
|
||||
|
||||
// None zero nonce
|
||||
let block_with_nonce = transform_block(block.clone(), |mut b| {
|
||||
b.header.nonce = 1;
|
||||
b
|
||||
});
|
||||
assert_matches!(
|
||||
TryInto::<SealedBlock>::try_into(block_with_nonce.clone()),
|
||||
Err(PayloadError::BlockHash { consensus, .. }) if consensus == block_with_nonce.block_hash
|
||||
);
|
||||
|
||||
// Valid block
|
||||
let valid_block = block;
|
||||
assert_matches!(TryInto::<SealedBlock>::try_into(valid_block), Ok(_));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serde_payload_status() {
|
||||
|
||||
Reference in New Issue
Block a user