1use crate::{
2 deposit_per_account, deposit_per_byte, deposit_per_item, hash_encoded, hash_raw_concat, simple::AuthWindow, CoreCount, Entropy, EpochPeriod, Mmr, RecentBlockCount, WorkReport
3};
4use bounded_collections::ConstU32;
5use jam_types::{
6 opaque, AuthQueue, AuthorizerHash, Balance, BoundedVec, CodeHash, FixedVec, HeaderHash,
7 SegmentTreeRoot, ServiceId, ServiceInfo, Slot, StateRootHash, UnsignedGas, VecMap, VecSet,
8 WorkPackageHash, WorkReportHash,
9};
10use scale::{Decode, Encode};
11
12opaque! {
13 pub struct StorageKey(pub [u8; 32]);
14}
15
16#[derive(Debug, Encode, Decode, Copy, Clone, Eq, PartialEq)]
17pub enum SystemKey {
18 Reserved0 = 0,
19 AuthPools = 1,
20 AuthQueues = 2,
21 RecentBlocks = 3,
22 Safrole = 4,
23 Disputes = 5,
24 Entropy = 6,
25 Designates = 7,
26 Validators = 8,
27 PrevValidators = 9,
28 Availability = 10,
29 CurrentTime = 11,
30 Privileges = 12,
31 Statistics = 13,
32 ReadyQueue = 14,
33 Accumulated = 15,
34}
35
36impl From<SystemKey> for StorageKey {
37 fn from(value: SystemKey) -> Self {
38 let k = value.encode();
39 let mut r = [0; 32];
40 r[..k.len()].copy_from_slice(&k[..]);
41 r.into()
42 }
43}
44
45impl IntoStorageKey for SystemKey {
46 fn service_id(&self) -> Option<ServiceId> {
47 None
48 }
49}
50
51#[derive(Clone)]
52pub enum ServiceKey<'a> {
53 Info { id: ServiceId },
54 Value { id: ServiceId, key: &'a [u8] },
55 Request { id: ServiceId, len: u32, hash: [u8; 32] },
56 Preimage { id: ServiceId, hash: [u8; 32] },
57}
58
59pub trait IntoStorageKey: Into<StorageKey> {
60 fn service_id(&self) -> Option<ServiceId>;
61}
62
63impl IntoStorageKey for ServiceKey<'_> {
64 fn service_id(&self) -> Option<ServiceId> {
65 Some(match self {
66 Self::Info { id, .. } |
67 Self::Value { id, .. } |
68 Self::Request { id, .. } |
69 Self::Preimage { id, .. } => *id,
70 })
71 }
72}
73
74impl<'a> From<ServiceKey<'a>> for StorageKey {
75 fn from(k: ServiceKey<'a>) -> Self {
76 use ServiceKey::*;
77 let id = match k {
78 Info { id } | Value { id, .. } | Request { id, .. } | Preimage { id, .. } => id,
79 }
80 .to_le_bytes();
81 let mut r = [0; 32];
82 let hash = match k {
83 Info { .. } => {
84 r[0] = 255;
85 r[1] = id[0];
86 r[3] = id[1];
87 r[5] = id[2];
88 r[7] = id[3];
89 return r.into();
90 },
91 Value { id, key } => {
92 let mut hash = hash_raw_concat([&id.to_le_bytes()[..], key]);
93 hash.copy_within(0..28, 4);
94 hash[..4].copy_from_slice(&[0xff, 0xff, 0xff, 0xff]);
95 hash
96 },
97 Preimage { mut hash, .. } => {
98 hash.copy_within(1..29, 4);
99 hash[..4].copy_from_slice(&[0xfe, 0xff, 0xff, 0xff]);
100 hash
101 },
102 Request { len, hash, .. } => {
103 let mut hash = hash_encoded(&hash);
104 hash.copy_within(2..30, 4);
105 hash[..4].copy_from_slice(&len.to_le_bytes());
106 hash
107 },
108 };
109 r[8..].copy_from_slice(&hash[4..28]);
110 r[..8].copy_from_slice(&[id[0], hash[0], id[1], hash[1], id[2], hash[2], id[3], hash[3]]);
111 r.into()
112 }
113}
114
115#[derive(Debug, Clone, Encode, Decode)]
116pub struct Service {
117 pub code_hash: CodeHash,
119 pub balance: Balance,
121 pub min_item_gas: UnsignedGas,
124 pub min_memo_gas: UnsignedGas,
127 pub bytes: u64,
129 pub items: u32,
131}
132
133impl From<Service> for ServiceInfo {
134 fn from(service: Service) -> Self {
135 ServiceInfo {
136 code_hash: service.code_hash,
137 balance: service.balance,
138 min_item_gas: service.min_item_gas,
139 min_memo_gas: service.min_memo_gas,
140 bytes: service.bytes,
141 items: service.items,
142 threshold: service.threshold(),
143 }
144 }
145}
146
147impl Service {
148 pub fn threshold(&self) -> Balance {
149 Self::deposit_required(self.items, self.bytes)
150 }
151 pub fn free(&self) -> Balance {
152 self.balance.saturating_sub(self.threshold())
153 }
154 pub fn deposit_required(items: u32, bytes: u64) -> u64 {
155 items as u64 * deposit_per_item() + bytes * deposit_per_byte() + deposit_per_account()
156 }
157}
158
159pub type AuthPool = BoundedVec<AuthorizerHash, AuthWindow>;
160pub type AuthPools = FixedVec<AuthPool, CoreCount>;
161pub type AuthQueues = FixedVec<AuthQueue, CoreCount>;
162
163#[derive(Debug, Encode, Decode, Eq, PartialEq, Clone)]
165pub struct BlockInfo {
166 pub hash: HeaderHash,
168 pub beefy_mmr: Mmr,
170 pub state_root: StateRootHash,
172 pub reported: VecMap<WorkPackageHash, SegmentTreeRoot>,
175}
176
177#[derive(Debug, Encode, Decode, Eq, PartialEq, Clone)]
178pub struct AvailabilityAssignment {
179 pub report: WorkReport,
181 pub report_slot: Slot,
183}
184
185#[derive(Clone, Encode, Decode, Debug, Eq, PartialEq, Default)]
186pub struct Privileges {
187 pub bless: ServiceId,
189 pub assign: ServiceId,
191 pub designate: ServiceId,
193 pub always_acc: VecMap<ServiceId, UnsignedGas>,
195}
196
197#[derive(Clone, Encode, Decode, Debug, Eq, PartialEq, Default)]
198pub struct Disputes {
199 pub good: VecSet<WorkReportHash>,
201 pub bad: VecSet<WorkReportHash>,
203 pub wonky: VecSet<WorkReportHash>,
205 pub offenders: VecSet<super::ed25519::Public>,
208}
209
210#[derive(Clone, Encode, Decode, Debug, Eq, PartialEq, Default)]
211pub struct ValActivityRecord {
212 pub blocks: u32,
214 pub tickets: u32,
216 pub preimages: u32,
218 pub preimages_size: u32,
220 pub guarantees: u32,
222 pub assurances: u32,
224}
225
226#[derive(Clone, Encode, Decode, Debug, Eq, PartialEq, Default)]
227pub struct ServiceActivityRecord {
228 #[codec(compact)]
230 pub provided_count: u16,
231 #[codec(compact)]
233 pub provided_size: u32,
234 #[codec(compact)]
236 pub refinement_count: u32,
237 #[codec(compact)]
239 pub refinement_gas_used: UnsignedGas,
240 #[codec(compact)]
242 pub imports: u32,
243 #[codec(compact)]
245 pub exports: u32,
246 #[codec(compact)]
248 pub extrinsic_size: u32,
249 #[codec(compact)]
251 pub extrinsic_count: u32,
252 #[codec(compact)]
254 pub accumulate_count: u32,
255 #[codec(compact)]
257 pub accumulate_gas_used: UnsignedGas,
258 #[codec(compact)]
260 pub on_transfers_count: u32,
261 #[codec(compact)]
263 pub on_transfers_gas_used: UnsignedGas,
264}
265
266#[derive(Clone, Encode, Decode, Debug, Eq, PartialEq, Default)]
267pub struct CoreActivityRecord {
268 #[codec(compact)]
273 pub da_load: u32,
274 #[codec(compact)]
276 pub popularity: u16,
277 #[codec(compact)]
279 pub imports: u16,
280 #[codec(compact)]
282 pub exports: u16,
283 #[codec(compact)]
285 pub extrinsic_size: u32,
286 #[codec(compact)]
288 pub extrinsic_count: u16,
289 #[codec(compact)]
291 pub bundle_size: u32,
292 #[codec(compact)]
295 pub gas_used: UnsignedGas,
296}
297
298pub type CoresStats = FixedVec<CoreActivityRecord, CoreCount>;
299pub type ServicesStats = VecMap<ServiceId, ServiceActivityRecord>;
300
301#[derive(Clone, Encode, Decode, Debug, Eq, PartialEq, Default)]
302pub struct Statistics {
303 pub vals_current: FixedVec<ValActivityRecord, jam_types::ValCount>,
304 pub vals_last: FixedVec<ValActivityRecord, jam_types::ValCount>,
305 pub cores: CoresStats,
306 pub services: ServicesStats,
307}
308
309impl Statistics {
310 pub fn reset(&mut self) {
312 self.cores = Default::default();
313 self.services = Default::default();
314 }
315}
316
317pub type EntropyBuffer = FixedVec<Entropy, ConstU32<4>>;
322
323pub type RecentBlocks = BoundedVec<BlockInfo, RecentBlockCount>;
324
325pub type AvailabilityAssignments = FixedVec<Option<AvailabilityAssignment>, CoreCount>;
326
327#[derive(Clone, Encode, Decode, Debug, Eq, PartialEq)]
328pub struct ReadyRecord {
329 pub report: WorkReport,
330 pub deps: VecSet<WorkPackageHash>,
331}
332pub type ReadyQueue = FixedVec<Vec<ReadyRecord>, EpochPeriod>;
333pub type Accumulated = FixedVec<Vec<WorkPackageHash>, EpochPeriod>;