croncat_tasks/
state.rs

1use cosmwasm_std::{Addr, Timestamp, Uint64};
2use croncat_sdk_tasks::types::{Boundary, Config, Task};
3use cw_storage_plus::{Index, IndexList, IndexedMap, Item, Map, MultiIndex};
4
5pub const CONFIG: Item<Config> = Item::new("config");
6
7/// Controls whether or not the contract is paused. Can only be changed to TRUE by
8/// the pause_admin, can only be unpaused by DAO/owner_addr
9pub const PAUSED: Item<bool> = Item::new("paused");
10
11/// Total amount of tasks
12pub const TASKS_TOTAL: Item<u64> = Item::new("tasks_total");
13
14/// Timestamps can be grouped into slot buckets (1-60 second buckets) for easier agent handling
15pub const TIME_SLOTS: Map<u64, Vec<Vec<u8>>> = Map::new("time_slots");
16
17/// Block slots allow for grouping of tasks at a specific block height,
18/// this is done instead of forcing a block height into a range of timestamps for reliability
19pub const BLOCK_SLOTS: Map<u64, Vec<Vec<u8>>> = Map::new("block_slots");
20
21/// Evented tasks, to keep track of tasks needing "check_result" to trigger tx
22/// key: Boundary Start - either height or time :: defaults to 0
23pub const EVENTED_TASKS_LOOKUP: Map<u64, Vec<Vec<u8>>> = Map::new("evented_task_lookup");
24
25/// Last task creation timestamp
26pub const LAST_TASK_CREATION: Item<Timestamp> = Item::new("last_task_creation");
27
28// TODO: make IndexedMap's const as soon as cw_storage_plus new version arrives
29pub fn tasks_map<'a>() -> IndexedMap<'a, &'a [u8], Task, TaskIndexes<'a>> {
30    let indexes = TaskIndexes {
31        owner: MultiIndex::new(owner_idx, "tasks", "tasks__owner"),
32        evented: MultiIndex::new(evented_idx, "tasks", "tasks__evented"),
33    };
34    IndexedMap::new("tasks", indexes)
35}
36
37pub struct TaskIndexes<'a> {
38    pub owner: MultiIndex<'a, Addr, Task, Addr>,
39    pub evented: MultiIndex<'a, u64, Task, u64>,
40}
41
42pub fn owner_idx(_pk: &[u8], d: &Task) -> Addr {
43    d.owner_addr.clone()
44}
45
46/// For filtering to tasks with queries (requiring 'check_result') that are also grouped by boundary (if any)
47pub fn evented_idx(_pk: &[u8], d: &Task) -> u64 {
48    if d.is_evented() {
49        let v = match d.boundary.clone() {
50            Boundary::Height(h) => h.start.unwrap_or(Uint64::zero()).into(),
51            Boundary::Time(t) => {
52                if let Some(n) = t.start {
53                    n.nanos()
54                } else {
55                    0
56                }
57            }
58        };
59        return v;
60    }
61    0
62}
63
64impl<'a> IndexList<Task> for TaskIndexes<'a> {
65    fn get_indexes(&'_ self) -> Box<dyn Iterator<Item = &'_ dyn Index<Task>> + '_> {
66        let v: Vec<&dyn Index<Task>> = vec![&self.owner, &self.evented];
67        Box::new(v.into_iter())
68    }
69}