use thiserror::Error;
use tenzro_types::primitives::BlockHeight;
pub type Result<T> = std::result::Result<T, ConsensusError>;
#[derive(Debug, Error)]
pub enum ConsensusError {
#[error("Invalid block proposal: {0}")]
InvalidProposal(String),
#[error("Invalid vote: {0}")]
InvalidVote(String),
#[error("Insufficient votes for quorum: got {got}, need {need}")]
InsufficientVotes { got: u64, need: u64 },
#[error("Vote from non-validator: {0}")]
NonValidator(String),
#[error("Block already exists at height {0}")]
DuplicateBlock(BlockHeight),
#[error("Block not found at height {0}")]
BlockNotFound(BlockHeight),
#[error("Invalid block height: expected {expected}, got {actual}")]
InvalidHeight {
expected: BlockHeight,
actual: BlockHeight,
},
#[error("Invalid block hash: expected {expected}, got {actual}")]
InvalidHash { expected: String, actual: String },
#[error("Invalid signature: {0}")]
InvalidSignature(String),
#[error("View {0} timed out")]
ViewTimeout(u64),
#[error("Not the leader for view {0}")]
NotLeader(u64),
#[error("Already voted in view {0}")]
AlreadyVoted(u64),
#[error("Invalid validator set: {0}")]
InvalidValidatorSet(String),
#[error("Epoch transition error: {0}")]
EpochTransition(String),
#[error("Mempool error: {0}")]
Mempool(String),
#[error("Invalid TEE attestation: {0}")]
InvalidAttestation(String),
#[error("Configuration error: {0}")]
Configuration(String),
#[error("Cryptographic error: {0}")]
Crypto(String),
#[error("Internal error: {0}")]
Internal(String),
#[error("Consensus engine not started")]
NotStarted,
#[error("Consensus engine already started")]
AlreadyStarted,
#[error("Equivocation detected: validator {validator} voted for multiple blocks in view {view}")]
Equivocation { validator: String, view: u64 },
#[error("Rate limit exceeded for lane {lane}: retry after {retry_after_ms}ms (rate {current_rate}/s)")]
RateLimited {
lane: &'static str,
retry_after_ms: u64,
burst_remaining: u32,
current_rate: f64,
},
#[error(
"Fee floor not met for {lane} lane: gas_price {gas_price} < required {required} \
(base {base} × {multiplier:.2})"
)]
FeeFloorTooLow {
lane: &'static str,
gas_price: u64,
required: u64,
base: u64,
multiplier: f64,
},
}
impl From<tenzro_crypto::CryptoError> for ConsensusError {
fn from(err: tenzro_crypto::CryptoError) -> Self {
ConsensusError::Crypto(err.to_string())
}
}
impl From<tenzro_crypto::bls::BlsError> for ConsensusError {
fn from(err: tenzro_crypto::bls::BlsError) -> Self {
ConsensusError::Crypto(err.to_string())
}
}