chia-sdk-test 0.36.0

A wallet simulator and related tooling for testing Chia wallet code.
Documentation
use std::io;

use chia_consensus::validation_error::ErrorCode;
#[cfg(feature = "serde")]
use chia_protocol::Bytes32;
use chia_sdk_signer::SignerError;
use thiserror::Error;

#[derive(Debug, Error)]
pub enum SimulatorError {
    #[error("IO error: {0}")]
    Io(#[from] io::Error),

    #[error("Validation error: {0:?}")]
    Validation(ErrorCode),

    #[error("Signer error: {0}")]
    Signer(#[from] SignerError),

    #[error("Missing key")]
    MissingKey,

    #[error(transparent)]
    ChainState(#[from] ChainStateError),

    #[cfg(feature = "serde")]
    #[error(transparent)]
    StateDump(#[from] StateDumpError),
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Error)]
pub enum ChainStateError {
    #[error("canonical height has no tip header")]
    MissingTipHeader,

    #[error("canonical tip block is missing")]
    MissingTipBlock,

    #[error("block height does not extend the canonical chain")]
    InvalidBlockHeight,

    #[error("block previous hash does not match the canonical tip")]
    InvalidPreviousHash,

    #[error("block timestamp does not match the next timestamp")]
    InvalidBlockTimestamp,

    #[error("block header is already canonical")]
    DuplicateBlockHeader,

    #[error("block is not the canonical tip")]
    BlockIsNotTip,

    #[error("block delta changes a coin more than once")]
    DuplicateCoinChange,

    #[error("block delta changes a coin spend more than once")]
    DuplicateSpendChange,

    #[error("block delta changes a coin hint more than once")]
    DuplicateHintChange,

    #[error("coin state does not match block delta")]
    CoinStateMismatch,

    #[error("coin spend state does not match block delta")]
    CoinSpendStateMismatch,

    #[error("coin hint state does not match block delta")]
    CoinHintStateMismatch,
}

#[cfg(feature = "serde")]
#[derive(Debug, Error)]
pub enum StateDumpError {
    #[error("failed to serialize simulator state: {0}")]
    Serialize(String),

    #[error("failed to deserialize simulator state: {0}")]
    Deserialize(String),

    #[error("missing canonical block {0}")]
    MissingCanonicalBlock(Bytes32),

    #[error("cannot dump state with canonical spend of unsupported manual coin {0}")]
    UnsupportedManualCoinSpend(Bytes32),

    #[error("block key {block_key} does not match record header hash {record_header_hash}")]
    BlockHeaderMismatch {
        block_key: Bytes32,
        record_header_hash: Bytes32,
    },

    #[error("canonical block is missing a timestamp")]
    MissingBlockTimestamp,

    #[error("{0} contain a duplicate key")]
    DuplicateKey(&'static str),

    #[error("previous coin record does not match replayed state for {0}")]
    PreviousCoinRecordMismatch(Bytes32),

    #[error("previous coin records contain an unchanged coin")]
    PreviousCoinRecordForUnchangedCoin,

    #[error("missing final coin record for addition {0}")]
    MissingFinalCoinRecord(Bytes32),

    #[error("added coin record is inconsistent with block {0}")]
    InconsistentAddedCoinRecord(u32),

    #[error("block removes unknown coin {0}")]
    UnknownRemovedCoin(Bytes32),

    #[error("block spends contain a duplicate coin")]
    DuplicateBlockSpend,

    #[error("block spend is not listed as a removal")]
    SpendNotRemoval,

    #[error("coin spend does not match final index for {0}")]
    CoinSpendIndexMismatch(Bytes32),

    #[error("block hint is not for an added coin")]
    HintNotAddition,

    #[error("missing final hint for coin {0}")]
    MissingFinalHint(Bytes32),

    #[error("coin hint does not match canonical transaction for {0}")]
    CoinHintMismatch(Bytes32),

    #[error("block additions do not match canonical transactions")]
    BlockAdditionsMismatch,

    #[error("block removals do not match canonical transactions")]
    BlockRemovalsMismatch,

    #[error("block spends do not match canonical transactions")]
    BlockSpendsMismatch,

    #[error("block hints do not match canonical transactions")]
    BlockHintsMismatch,

    #[error("serialized {0} do not match canonical blocks")]
    SerializedIndexMismatch(&'static str),

    #[error("unsupported full node simulator state format {0}")]
    UnsupportedFormat(String),

    #[error("unsupported full node simulator state version {0}")]
    UnsupportedVersion(u32),

    #[error("height {height} does not match {header_count} header hashes")]
    HeightHeaderCountMismatch { height: u32, header_count: usize },

    #[error("{header_count} canonical headers do not match {block_count} blocks")]
    HeaderBlockCountMismatch {
        header_count: usize,
        block_count: usize,
    },

    #[error("coin record key does not match coin id {0}")]
    CoinRecordKeyMismatch(Bytes32),

    #[error("coin spend key does not match coin id {0}")]
    CoinSpendKeyMismatch(Bytes32),

    #[error("invalid master secret key: {0}")]
    InvalidMasterSecretKey(String),

    #[error("canonical genesis block is missing a timestamp")]
    MissingGenesisTimestamp,

    #[error("canonical block ordering does not match header hashes")]
    CanonicalBlockOrderMismatch,

    #[error("replayed height does not match serialized height")]
    ReplayedHeightMismatch,

    #[error("next timestamp does not follow the canonical blocks")]
    NextTimestampMismatch,
}