use cosmwasm_schema::cw_serde;
use cosmwasm_std::{Addr, Uint128};
use cw_storage_plus::{Item, Map};

/// Sliding window entry: one accepted proof.
#[cw_serde]
pub struct WindowEntry {
    pub difficulty: u32,
    pub timestamp: u64,
}

/// Ring-buffer sliding window over the last N proofs.
#[cw_serde]
pub struct SlidingWindow {
    /// Fixed-size ring buffer of window entries.
    pub entries: Vec<WindowEntry>,
    /// Next write position in the ring buffer (wraps at window_size).
    pub head: u32,
    /// Total proofs ever accepted (monotonic counter).
    pub count: u64,
    /// Sum of difficulty bits across entries currently in the window.
    pub total_d: u64,
    /// Timestamp of the oldest entry in the window.
    pub t_first: u64,
    /// Timestamp of the newest entry in the window.
    pub t_last: u64,
}

/// PID controller state for adaptive alpha/beta tuning.
#[cw_serde]
pub struct PidState {
    /// Allocation curve exponent [0.3, 0.7].
    pub alpha: u64,
    /// Fee burn rate [0.0, 0.9], stored as micros (0..900_000).
    pub beta: u64,
    /// Previous efficiency error (scaled by 1e9).
    pub e_eff_prev: i64,
    /// Previous fee coverage error (scaled by 1e9).
    pub e_cov_prev: i64,
    /// EMA of efficiency error derivative (scaled by 1e9).
    pub de_eff: i64,
    /// EMA of fee coverage error derivative (scaled by 1e9).
    pub de_cov: i64,
    /// Cached S^alpha as micros [0, MICROS], updated each PID cycle.
    pub cached_staking_share: u64,
}

/// A single time-bucketed fee accumulator.
#[cw_serde]
pub struct FeeBucket {
    /// Epoch index = timestamp / bucket_duration.
    pub epoch: u64,
    /// Raw fee amount accumulated in this bucket (before beta burn).
    pub amount: Uint128,
}

/// Rolling fee history: fixed-size ring of time buckets.
#[cw_serde]
pub struct FeeHistory {
    /// Fixed-size ring buffer of fee buckets.
    pub buckets: Vec<FeeBucket>,
    /// Seconds per bucket (default 600).
    pub bucket_duration: u64,
}

/// Contract configuration.
#[cw_serde]
pub struct MineConfig {
    /// Maximum proof age in seconds.
    pub max_proof_age: u64,
    /// Estimated gas cost in uboot for submitting a proof.
    pub estimated_gas_cost_uboot: Uint128,
    /// litium-core contract address (for mint requests).
    pub core_contract: Addr,
    /// litium-stake contract address (for staking reward accrual).
    pub stake_contract: Addr,
    /// litium-refer contract address (for referral binding/accrual).
    pub refer_contract: Addr,
    /// Token denom (factory/{core_contract}/{subdenom}).
    pub token_contract: String,
    /// Admin address.
    pub admin: Addr,
    /// Whether contract is paused.
    pub paused: bool,
    /// Sliding window size N (number of proof entries).
    pub window_size: u32,
    /// PID update interval: run PID every K proofs.
    pub pid_interval: u64,
    /// Contract genesis timestamp (seconds) โ€” anchor for emission curve.
    pub genesis_time: u64,
    /// Fixed base_rate during warmup (first N proofs, before window is full).
    pub warmup_base_rate: Uint128,
    /// Seconds per fee bucket (default 600).
    pub fee_bucket_duration: u64,
    /// Number of fee buckets in ring buffer (default 36).
    pub fee_num_buckets: u32,
}

/// Global statistics.
#[cw_serde]
pub struct Stats {
    pub total_proofs: u64,
    pub total_rewards: Uint128,
    pub unique_miners: u64,
    pub total_difficulty_bits: u64,
}

/// Per-miner statistics.
#[cw_serde]
pub struct MinerStats {
    pub proofs_submitted: u64,
    pub total_rewards: Uint128,
    pub last_proof_time: u64,
}

// Storage keys
pub const CONFIG: Item<MineConfig> = Item::new("config");
pub const STATS: Item<Stats> = Item::new("stats");
pub const SLIDING_WINDOW: Item<SlidingWindow> = Item::new("sliding_window");
pub const PID_STATE: Item<PidState> = Item::new("pid_state");
pub const FEE_HISTORY: Item<FeeHistory> = Item::new("fee_history");

/// Miner statistics by address.
pub const MINER_STATS: Map<&Addr, MinerStats> = Map::new("miner_stats");

/// Used proof hashes to prevent replay. Value is the proof timestamp for pruning.
pub const USED_PROOF_HASHES: Map<&[u8], u64> = Map::new("used_proof_hashes");

/// Cursor for amortized proof hash pruning (last key scanned).
pub const PROOF_PRUNE_CURSOR: Item<Vec<u8>> = Item::new("proof_prune_cursor");

Dimensions

cw-cyber/contracts/cw-cyber-gift/src/state.rs
cw-cyber/contracts/cw-cyber-subgraph/src/state.rs
cw-cyber/contracts/cybernet/src/state.rs
cw-cyber/contracts/hub-libs/src/state.rs
cw-cyber/contracts/litium-wrap/src/state.rs
cw-cyber/contracts/litium-refer/src/state.rs
cw-cyber/contracts/graph-filter/src/state.rs
cw-cyber/contracts/litium-stake/src/state.rs
cw-cyber/contracts/hub-networks/src/state.rs
cw-cyber/contracts/hub-skills/src/state.rs
cw-cyber/contracts/hub-protocols/src/state.rs
cw-cyber/contracts/hub-tokens/src/state.rs
cw-cyber/contracts/std-test/src/state.rs
cw-cyber/contracts/hub-channels/src/state.rs
cw-cyber/contracts/cw-cyber-passport/src/state.rs
cw-cyber/contracts/litium-core/src/state.rs
cw-cyber/packages/hub-base/src/state.rs

Local Graph