use crate::types::{InvalidBlockBodyError, InvalidBlockHeaderError};

/// Errors that occur during block validation.
///
/// These are validation errors that don't require storage access to detect.
#[derive(Debug, thiserror::Error)]
pub enum InvalidBlockError {
    #[error("Requests hash does not match the one in the header after executing")]
    RequestsHashMismatch,
    #[error("Block access list hash does not match the one in the header after executing")]
    BlockAccessListHashMismatch,
    #[error("Block access list contains index {index} exceeding max valid index {max}")]
    BlockAccessListIndexOutOfBounds { index: u32, max: u32 },
    #[error("Block access list exceeds gas limit, {items} items exceeds limit of {max_items}")]
    BlockAccessListSizeExceeded { items: u64, max_items: u64 },
    #[error("World State Root does not match the one in the header after executing")]
    StateRootMismatch,
    #[error("Receipts Root does not match the one in the header after executing")]
    ReceiptsRootMismatch,
    #[error("Logs bloom does not match the one in the header after executing")]
    LogsBloomMismatch,
    #[error("Invalid Header, validation failed pre-execution: {0}")]
    InvalidHeader(#[from] InvalidBlockHeaderError),
    #[error("Invalid Body, validation failed pre-execution: {0}")]
    InvalidBody(#[from] InvalidBlockBodyError),
    #[error("Exceeded MAX_BLOB_GAS_PER_BLOCK")]
    ExceededMaxBlobGasPerBlock,
    #[error("Exceeded MAX_BLOB_NUMBER_PER_BLOCK")]
    ExceededMaxBlobNumberPerBlock,
    #[error("Gas used doesn't match value in header. Used: {0}, Expected: {1}")]
    GasUsedMismatch(u64, u64),
    #[error("Blob gas used doesn't match value in header")]
    BlobGasUsedMismatch,
    #[error("Invalid transaction: {0}")]
    InvalidTransaction(String),
    #[error("Maximum block size exceeded: Maximum is {0} MiB, but block was {1} MiB")]
    MaximumRlpSizeExceeded(u64, u64),
    #[error("Invalid block fork")]
    InvalidBlockFork,
    #[error("Transaction type {0:#x} is not allowed in an L1 block")]
    UnsupportedTransactionType(u8),
    #[error("Transaction has invalid chain id: have {have}, want {want}")]
    InvalidTransactionChainId { have: u64, want: u64 },
}
