use crate::primitives::Bytes32;
use thiserror::Error;
#[derive(Debug, Clone, Error)]
pub enum BlockError {
#[error("invalid data: {0}")]
InvalidData(String),
#[error("invalid version: expected {expected}, got {actual}")]
InvalidVersion { expected: u16, actual: u16 },
#[error("block too large: {size} bytes exceeds max {max}")]
TooLarge { size: u32, max: u32 },
#[error("cost exceeded: {cost} exceeds max {max}")]
CostExceeded { cost: u64, max: u64 },
#[error("spend bundle count mismatch: header={header}, actual={actual}")]
SpendBundleCountMismatch { header: u32, actual: u32 },
#[error("invalid spends root: expected={expected}, computed={computed}")]
InvalidSpendsRoot {
expected: Bytes32,
computed: Bytes32,
},
#[error("invalid receipts root: expected={expected}, computed={computed}")]
InvalidReceiptsRoot {
expected: Bytes32,
computed: Bytes32,
},
#[error("invalid parent: expected={expected}, got={got}")]
InvalidParent { expected: Bytes32, got: Bytes32 },
#[error("invalid slash proposals root")]
InvalidSlashProposalsRoot,
#[error("slash proposal payload too large")]
SlashProposalPayloadTooLarge,
#[error("too many slash proposals")]
TooManySlashProposals,
#[error("invalid additions root")]
InvalidAdditionsRoot,
#[error("invalid removals root")]
InvalidRemovalsRoot,
#[error("invalid filter hash")]
InvalidFilterHash,
#[error("duplicate output: coin_id={coin_id}")]
DuplicateOutput { coin_id: Bytes32 },
#[error("double spend in block: coin_id={coin_id}")]
DoubleSpendInBlock { coin_id: Bytes32 },
#[error("additions count mismatch: header={header}, actual={actual}")]
AdditionsCountMismatch { header: u32, actual: u32 },
#[error("removals count mismatch: header={header}, actual={actual}")]
RemovalsCountMismatch { header: u32, actual: u32 },
#[error("slash proposal count mismatch: header={header}, actual={actual}")]
SlashProposalCountMismatch { header: u32, actual: u32 },
#[error("timestamp too far in future: {timestamp} exceeds max_allowed {max_allowed}")]
TimestampTooFarInFuture { timestamp: u64, max_allowed: u64 },
#[error("puzzle hash mismatch for coin {coin_id}: expected={expected}, computed={computed}")]
PuzzleHashMismatch {
coin_id: Bytes32,
expected: Bytes32,
computed: Bytes32,
},
#[error("CLVM execution failed for coin {coin_id}: {reason}")]
ClvmExecutionFailed { coin_id: Bytes32, reason: String },
#[error("CLVM cost exceeded for coin {coin_id}: cost={cost}, remaining={remaining}")]
ClvmCostExceeded {
coin_id: Bytes32,
cost: u64,
remaining: u64,
},
#[error("assertion failed: condition={condition}, reason={reason}")]
AssertionFailed { condition: String, reason: String },
#[error("announcement not found: {announcement_hash}")]
AnnouncementNotFound { announcement_hash: Bytes32 },
#[error("signature verification failed for bundle index {bundle_index}")]
SignatureFailed { bundle_index: u32 },
#[error("coin minting: removed={removed}, added={added}")]
CoinMinting { removed: u64, added: u64 },
#[error("fees mismatch: header={header}, computed={computed}")]
FeesMismatch { header: u64, computed: u64 },
#[error("reserve fee failed: required={required}, actual={actual}")]
ReserveFeeFailed { required: u64, actual: u64 },
#[error("cost mismatch: header={header}, computed={computed}")]
CostMismatch { header: u64, computed: u64 },
#[error("invalid proposer signature")]
InvalidProposerSignature,
#[error("block not found: {0}")]
NotFound(Bytes32),
#[error("invalid state root: expected={expected}, computed={computed}")]
InvalidStateRoot {
expected: Bytes32,
computed: Bytes32,
},
#[error("coin not found: {coin_id}")]
CoinNotFound { coin_id: Bytes32 },
#[error("coin already spent: {coin_id} at height {spent_height}")]
CoinAlreadySpent { coin_id: Bytes32, spent_height: u64 },
#[error("coin already exists: {coin_id}")]
CoinAlreadyExists { coin_id: Bytes32 },
}
#[derive(Debug, Clone, Error)]
pub enum CheckpointError {
#[error("invalid checkpoint data: {0}")]
InvalidData(String),
#[error("checkpoint not found for epoch {0}")]
NotFound(u64),
#[error("invalid checkpoint: {0}")]
Invalid(String),
#[error("score not higher: current={current}, submitted={submitted}")]
ScoreNotHigher { current: u64, submitted: u64 },
#[error("epoch mismatch: expected={expected}, got={got}")]
EpochMismatch { expected: u64, got: u64 },
#[error("checkpoint already finalized")]
AlreadyFinalized,
#[error("checkpoint process not started")]
NotStarted,
}
#[derive(Debug, Clone, Error)]
pub enum BuilderError {
#[error("cost budget exceeded: current={current}, addition={addition}, max={max}")]
CostBudgetExceeded {
current: u64,
addition: u64,
max: u64,
},
#[error("size budget exceeded: current={current}, addition={addition}, max={max}")]
SizeBudgetExceeded {
current: u32,
addition: u32,
max: u32,
},
#[error("too many slash proposals: max={max}")]
TooManySlashProposals { max: u32 },
#[error("slash proposal too large: size={size}, max={max}")]
SlashProposalTooLarge { size: u32, max: u32 },
#[error("signing failed: {0}")]
SigningFailed(String),
#[error("empty block: no spend bundles added")]
EmptyBlock,
#[error("missing DFSP roots")]
MissingDfspRoots,
}
#[derive(Debug, Clone, Error, PartialEq, Eq)]
pub enum SignerBitmapError {
#[error("index out of bounds: index={index}, max={max}")]
IndexOutOfBounds { index: u32, max: u32 },
#[error("too many validators: {0}")]
TooManyValidators(usize),
#[error("invalid bitmap length: expected={expected}, got={got}")]
InvalidLength { expected: usize, got: usize },
#[error("validator count mismatch: expected={expected}, got={got}")]
ValidatorCountMismatch { expected: u32, got: u32 },
}
#[derive(Debug, Clone, Error, PartialEq, Eq)]
pub enum ReceiptError {
#[error("invalid receipt data: {0}")]
InvalidData(String),
#[error("receipt not found: {0}")]
NotFound(Bytes32),
}