chore: rm unused consensus fns (#7972)

This commit is contained in:
Oliver Nordbjerg
2024-04-29 23:45:21 +02:00
committed by GitHub
parent 6619faf42b
commit d9faaa80cf

View File

@ -7,12 +7,9 @@ use reth_primitives::{
eip4844::{DATA_GAS_PER_BLOB, MAX_DATA_GAS_PER_BLOCK},
MAXIMUM_EXTRA_DATA_SIZE,
},
BlockNumber, ChainSpec, GotExpected, Hardfork, Header, InvalidTransactionError, SealedBlock,
SealedHeader, Transaction, TransactionSignedEcRecovered, TxEip1559, TxEip2930, TxEip4844,
TxLegacy,
ChainSpec, GotExpected, Hardfork, Header, SealedBlock, SealedHeader,
};
use reth_provider::{AccountReader, HeaderProvider, WithdrawalsProvider};
use std::collections::{hash_map::Entry, HashMap};
use reth_provider::{HeaderProvider, WithdrawalsProvider};
/// Validate header standalone
pub fn validate_header_standalone(
@ -59,148 +56,6 @@ pub fn validate_header_standalone(
Ok(())
}
/// Validate a transaction with regard to a block header.
///
/// The only parameter from the header that affects the transaction is `base_fee`.
pub fn validate_transaction_regarding_header(
transaction: &Transaction,
chain_spec: &ChainSpec,
at_block_number: BlockNumber,
at_timestamp: u64,
base_fee: Option<u64>,
) -> Result<(), ConsensusError> {
#[allow(unreachable_patterns)]
let chain_id = match transaction {
Transaction::Legacy(TxLegacy { chain_id, .. }) => {
// EIP-155: Simple replay attack protection: https://eips.ethereum.org/EIPS/eip-155
if !chain_spec.fork(Hardfork::SpuriousDragon).active_at_block(at_block_number) &&
chain_id.is_some()
{
return Err(InvalidTransactionError::OldLegacyChainId.into())
}
*chain_id
}
Transaction::Eip2930(TxEip2930 { chain_id, .. }) => {
// EIP-2930: Optional access lists: https://eips.ethereum.org/EIPS/eip-2930 (New transaction type)
if !chain_spec.fork(Hardfork::Berlin).active_at_block(at_block_number) {
return Err(InvalidTransactionError::Eip2930Disabled.into())
}
Some(*chain_id)
}
Transaction::Eip1559(TxEip1559 {
chain_id,
max_fee_per_gas,
max_priority_fee_per_gas,
..
}) => {
// EIP-1559: Fee market change for ETH 1.0 chain https://eips.ethereum.org/EIPS/eip-1559
if !chain_spec.fork(Hardfork::London).active_at_block(at_block_number) {
return Err(InvalidTransactionError::Eip1559Disabled.into())
}
// EIP-1559: add more constraints to the tx validation
// https://github.com/ethereum/EIPs/pull/3594
if max_priority_fee_per_gas > max_fee_per_gas {
return Err(InvalidTransactionError::TipAboveFeeCap.into())
}
Some(*chain_id)
}
Transaction::Eip4844(TxEip4844 {
chain_id,
max_fee_per_gas,
max_priority_fee_per_gas,
..
}) => {
// EIP-4844: Shard Blob Transactions https://eips.ethereum.org/EIPS/eip-4844
if !chain_spec.is_cancun_active_at_timestamp(at_timestamp) {
return Err(InvalidTransactionError::Eip4844Disabled.into())
}
// EIP-1559: add more constraints to the tx validation
// https://github.com/ethereum/EIPs/pull/3594
if max_priority_fee_per_gas > max_fee_per_gas {
return Err(InvalidTransactionError::TipAboveFeeCap.into())
}
Some(*chain_id)
}
_ => {
// Op Deposit
None
}
};
if let Some(chain_id) = chain_id {
if chain_id != chain_spec.chain().id() {
return Err(InvalidTransactionError::ChainIdMismatch.into())
}
}
// Check basefee and few checks that are related to that.
// https://github.com/ethereum/EIPs/pull/3594
if let Some(base_fee_per_gas) = base_fee {
if transaction.max_fee_per_gas() < base_fee_per_gas as u128 {
return Err(InvalidTransactionError::FeeCapTooLow.into())
}
}
Ok(())
}
/// Iterate over all transactions, validate them against each other and against the block.
/// There is no gas check done as [REVM](https://github.com/bluealloy/revm/blob/fd0108381799662098b7ab2c429ea719d6dfbf28/crates/revm/src/evm_impl.rs#L113-L131) already checks that.
pub fn validate_all_transaction_regarding_block_and_nonces<
'a,
Provider: HeaderProvider + AccountReader,
>(
transactions: impl Iterator<Item = &'a TransactionSignedEcRecovered>,
header: &Header,
provider: Provider,
chain_spec: &ChainSpec,
) -> RethResult<()> {
let mut account_nonces = HashMap::new();
for transaction in transactions {
validate_transaction_regarding_header(
transaction,
chain_spec,
header.number,
header.timestamp,
header.base_fee_per_gas,
)?;
// Get nonce, if there is previous transaction from same sender we need
// to take that nonce.
let nonce = match account_nonces.entry(transaction.signer()) {
Entry::Occupied(mut entry) => {
let nonce = *entry.get();
*entry.get_mut() += 1;
nonce
}
Entry::Vacant(entry) => {
let account = provider.basic_account(transaction.signer())?.unwrap_or_default();
// Signer account shouldn't have bytecode. Presence of bytecode means this is a
// smartcontract.
if account.has_bytecode() {
return Err(ConsensusError::from(
InvalidTransactionError::SignerAccountHasBytecode,
)
.into())
}
let nonce = account.nonce;
entry.insert(account.nonce + 1);
nonce
}
};
// check nonce
if transaction.nonce() != nonce {
return Err(ConsensusError::from(InvalidTransactionError::NonceNotConsistent).into())
}
}
Ok(())
}
/// Validate a block without regard for state:
///
/// - Compares the ommer hash in the block header to the block body
@ -345,10 +200,11 @@ mod tests {
test_utils::generators::{self, Rng},
};
use reth_primitives::{
hex_literal::hex, proofs, Account, Address, BlockBody, BlockHash, BlockHashOrNumber, Bytes,
ChainSpecBuilder, Signature, TransactionSigned, TxKind, Withdrawal, Withdrawals, MAINNET,
U256,
hex_literal::hex, proofs, Account, Address, BlockBody, BlockHash, BlockHashOrNumber,
BlockNumber, Bytes, ChainSpecBuilder, Signature, Transaction, TransactionSigned, TxEip4844,
TxKind, Withdrawal, Withdrawals, U256,
};
use reth_provider::AccountReader;
use std::ops::RangeBounds;
mock! {
@ -382,15 +238,6 @@ mod tests {
withdrawals_provider: MockWithdrawalsProvider::new(),
}
}
/// New provider where is_known is always true
fn new_known() -> Self {
Self {
is_known: true,
parent: None,
account: None,
withdrawals_provider: MockWithdrawalsProvider::new(),
}
}
}
impl AccountReader for Provider {
@ -457,25 +304,6 @@ mod tests {
}
}
fn mock_tx(nonce: u64) -> TransactionSignedEcRecovered {
let request = Transaction::Eip2930(TxEip2930 {
chain_id: 1u64,
nonce,
gas_price: 0x28f000fff,
gas_limit: 10,
to: TxKind::Call(Address::default()),
value: U256::from(3_u64),
input: Bytes::from(vec![1, 2]),
access_list: Default::default(),
});
let signature = Signature { odd_y_parity: true, r: U256::default(), s: U256::default() };
let tx = TransactionSigned::from_transaction_and_signature(request, signature);
let signer = Address::ZERO;
TransactionSignedEcRecovered::from_signed_transaction(tx, signer)
}
fn mock_blob_tx(nonce: u64, num_blobs: usize) -> TransactionSigned {
let mut rng = generators::rng();
let request = Transaction::Eip4844(TxEip4844 {
@ -539,60 +367,6 @@ mod tests {
(SealedBlock { header: header.seal_slow(), body, ommers, withdrawals: None }, parent)
}
#[test]
fn sanity_tx_nonce_check() {
let (block, _) = mock_block();
let tx1 = mock_tx(0);
let tx2 = mock_tx(1);
let provider = Provider::new_known();
let txs = vec![tx1, tx2];
validate_all_transaction_regarding_block_and_nonces(
txs.iter(),
&block.header,
provider,
&MAINNET,
)
.expect("To Pass");
}
#[test]
fn nonce_gap_in_first_transaction() {
let (block, _) = mock_block();
let tx1 = mock_tx(1);
let provider = Provider::new_known();
let txs = vec![tx1];
assert_eq!(
validate_all_transaction_regarding_block_and_nonces(
txs.iter(),
&block.header,
provider,
&MAINNET,
),
Err(ConsensusError::from(InvalidTransactionError::NonceNotConsistent).into())
)
}
#[test]
fn nonce_gap_on_second_tx_from_same_signer() {
let (block, _) = mock_block();
let tx1 = mock_tx(0);
let tx2 = mock_tx(3);
let provider = Provider::new_known();
let txs = vec![tx1, tx2];
assert_eq!(
validate_all_transaction_regarding_block_and_nonces(
txs.iter(),
&block.header,
provider,
&MAINNET,
),
Err(ConsensusError::from(InvalidTransactionError::NonceNotConsistent).into())
);
}
#[test]
fn valid_withdrawal_index() {
let chain_spec = ChainSpecBuilder::mainnet().shanghai_activated().build();