1use std::collections::{BTreeMap, HashMap};
5
6use serde::{Deserialize, Serialize};
7
8use crate::{
9 websocket::BLS12381_PUBLIC_KEY_SIZE, OracleDutyConfig, OracleId, OracleUpdateResult,
10 TimestampMs,
11};
12
13pub type AuthorityKeyBytes = [u8; BLS12381_PUBLIC_KEY_SIZE];
17
18pub type CommitIndex = u64;
22
23pub type OracleDutiesMap = BTreeMap<OracleDutiesMapKey, OracleDutiesMapValue>;
32
33#[derive(Clone, Copy, Debug, Serialize, Deserialize, Eq, PartialEq, Hash)]
35pub struct OracleDutiesMapKey {
36 pub target_timestamp: TimestampMs,
37 pub oracle_id: OracleId,
38}
39
40impl Ord for OracleDutiesMapKey {
42 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
43 self.target_timestamp
44 .cmp(&other.target_timestamp)
45 .then_with(|| self.oracle_id.cmp(&other.oracle_id))
46 }
47}
48
49impl PartialOrd for OracleDutiesMapKey {
50 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
51 Some(self.cmp(other))
52 }
53}
54
55#[derive(Clone, Debug, Serialize, Deserialize, Default)]
57pub struct OracleDutiesMapValue {
58 #[serde(with = "serde_utils")]
63 pub updates: HashMap<AuthorityKeyBytes, Option<OracleUpdateResult>>,
64
65 pub config: OracleDutyConfig,
68}
69
70mod serde_utils {
72 use std::collections::HashMap;
73
74 use serde::{Deserialize, Deserializer, Serialize, Serializer};
75 use serde_big_array::BigArray;
76
77 use super::{AuthorityKeyBytes, OracleUpdateResult};
78
79 pub fn serialize<S>(
80 map: &HashMap<AuthorityKeyBytes, Option<OracleUpdateResult>>,
81 serializer: S,
82 ) -> Result<S::Ok, S::Error>
83 where
84 S: Serializer,
85 {
86 #[derive(Serialize)]
87 struct Entry {
88 #[serde(with = "BigArray")]
89 key: AuthorityKeyBytes,
90 value: Option<OracleUpdateResult>,
91 }
92
93 let entries: Vec<_> = map
94 .iter()
95 .map(|(key, value)| Entry {
96 key: *key,
97 value: value.clone(),
98 })
99 .collect();
100 entries.serialize(serializer)
101 }
102
103 pub fn deserialize<'de, D>(
104 deserializer: D,
105 ) -> Result<HashMap<AuthorityKeyBytes, Option<OracleUpdateResult>>, D::Error>
106 where
107 D: Deserializer<'de>,
108 {
109 #[derive(Deserialize)]
110 struct Entry {
111 #[serde(with = "BigArray")]
112 key: AuthorityKeyBytes,
113 value: Option<OracleUpdateResult>,
114 }
115
116 let entries = Vec::<Entry>::deserialize(deserializer)?;
117 Ok(entries.into_iter().map(|e| (e.key, e.value)).collect())
118 }
119}
120
121#[cfg(test)]
122mod tests {
123 use std::cmp::{max, min};
124
125 use rialo_s_pubkey::Pubkey;
126
127 use super::*;
128
129 #[test]
130 fn test_oracle_duties_map_key_ordering() {
131 let creator1 = Pubkey::new_unique();
132 let creator2 = Pubkey::new_unique();
133 let oracle_id1 = OracleId::new(creator1, "nonce1");
134 let oracle_id2 = OracleId::new(creator2, "nonce2");
135 let [oracle_id1, oracle_id2] = [min(oracle_id1, oracle_id2), max(oracle_id1, oracle_id2)];
137 let key1 = OracleDutiesMapKey {
139 target_timestamp: 100,
140 oracle_id: oracle_id1,
141 };
142 let key2 = OracleDutiesMapKey {
143 target_timestamp: 200,
144 oracle_id: oracle_id1,
145 };
146 assert!(key1 < key2);
147 assert!(key2 > key1);
148
149 let key3 = OracleDutiesMapKey {
151 target_timestamp: 100,
152 oracle_id: oracle_id1,
153 };
154 let key4 = OracleDutiesMapKey {
155 target_timestamp: 100,
156 oracle_id: oracle_id2,
157 };
158 assert!(key3 < key4);
159 assert!(key4 > key3);
160
161 let key5 = OracleDutiesMapKey {
162 target_timestamp: 100,
163 oracle_id: oracle_id2,
164 };
165 let key6 = OracleDutiesMapKey {
166 target_timestamp: 200,
167 oracle_id: oracle_id1,
168 };
169 assert!(key5 < key6);
170 assert!(key6 > key5);
171
172 let key7 = OracleDutiesMapKey {
174 target_timestamp: 100,
175 oracle_id: oracle_id1,
176 };
177 let key8 = OracleDutiesMapKey {
178 target_timestamp: 100,
179 oracle_id: oracle_id1,
180 };
181 assert_eq!(key7, key8);
182 assert!(key7 >= key8);
183 assert!(key7 <= key8);
184
185 let mut map = BTreeMap::new();
187 let key9 = OracleDutiesMapKey {
188 target_timestamp: 200,
189 oracle_id: oracle_id1,
190 };
191 let key10 = OracleDutiesMapKey {
192 target_timestamp: 100,
193 oracle_id: oracle_id2,
194 };
195 let key11 = OracleDutiesMapKey {
196 target_timestamp: 100,
197 oracle_id: oracle_id1,
198 };
199
200 map.insert(key9, "first");
201 map.insert(key10, "second");
202 map.insert(key11, "third");
203
204 let keys: Vec<_> = map.keys().copied().collect();
205 assert_eq!(keys[0], key11);
206 assert_eq!(keys[1], key10);
207 assert_eq!(keys[2], key9);
208 }
209}