1use crate::{
2 deposit_per_account, deposit_per_byte, deposit_per_item, hash_encoded, hash_raw_concat,
3 simple::AuthWindow, CoreCount, Entropy, EpochPeriod, Mmr, RecentBlockCount, WorkReport,
4};
5use bounded_collections::ConstU32;
6use codec::{Decode, Encode};
7use jam_types::{
8 opaque, AuthQueue, AuthorizerHash, Balance, BoundedVec, CodeHash, FixedVec, HeaderHash,
9 SegmentTreeRoot, ServiceId, ServiceInfo, Slot, StateRootHash, UnsignedGas, VecMap, VecSet,
10 WorkPackageHash, WorkReportHash,
11};
12
13opaque! {
14 pub struct StorageKey(pub [u8; 31]);
15}
16
17#[derive(Debug, Encode, Decode, Copy, Clone, Eq, PartialEq)]
18pub enum SystemKey {
19 Reserved0 = 0,
20 AuthPools = 1,
21 AuthQueues = 2,
22 RecentBlocks = 3,
23 Safrole = 4,
24 Disputes = 5,
25 Entropy = 6,
26 Designates = 7,
27 Validators = 8,
28 PrevValidators = 9,
29 Availability = 10,
30 CurrentTime = 11,
31 Privileges = 12,
32 Statistics = 13,
33 ReadyQueue = 14,
34 Accumulated = 15,
35}
36
37impl From<SystemKey> for StorageKey {
38 fn from(value: SystemKey) -> Self {
39 let k = value.encode();
40 let mut r = [0; StorageKey::LEN];
41 r[..k.len()].copy_from_slice(&k[..]);
42 r.into()
43 }
44}
45
46impl IntoStorageKey for SystemKey {}
47
48impl IntoStorageKey for StorageKey {}
49
50#[derive(Clone)]
51pub enum ServiceKey<'a> {
52 Info { id: ServiceId },
53 Value { id: ServiceId, key: &'a [u8] },
54 Request { id: ServiceId, len: u32, hash: [u8; 32] },
55 Preimage { id: ServiceId, hash: [u8; 32] },
56}
57
58pub trait IntoStorageKey: Into<StorageKey> {
59 fn service_id(&self) -> Option<ServiceId> {
60 None
61 }
62}
63
64impl IntoStorageKey for ServiceKey<'_> {
65 fn service_id(&self) -> Option<ServiceId> {
66 Some(match self {
67 Self::Info { id, .. } |
68 Self::Value { id, .. } |
69 Self::Request { id, .. } |
70 Self::Preimage { id, .. } => *id,
71 })
72 }
73}
74
75impl<'a> From<ServiceKey<'a>> for StorageKey {
76 fn from(k: ServiceKey<'a>) -> Self {
77 use ServiceKey::*;
78 let id = match k {
79 Info { id } | Value { id, .. } | Request { id, .. } | Preimage { id, .. } => id,
80 }
81 .to_le_bytes();
82 let mut r = [0; StorageKey::LEN];
83 let hash = match k {
84 Info { .. } => {
85 r[0] = 255;
86 r[1] = id[0];
87 r[3] = id[1];
88 r[5] = id[2];
89 r[7] = id[3];
90 return r.into();
91 },
92 Value { id, key } => {
93 let mut hash = hash_raw_concat([&id.to_le_bytes()[..], key]);
94 hash.copy_within(0..28, 4);
95 hash[..4].copy_from_slice(&[0xff, 0xff, 0xff, 0xff]);
96 hash
97 },
98 Preimage { mut hash, .. } => {
99 hash.copy_within(1..29, 4);
100 hash[..4].copy_from_slice(&[0xfe, 0xff, 0xff, 0xff]);
101 hash
102 },
103 Request { len, hash, .. } => {
104 let mut hash = hash_encoded(&hash);
105 hash.copy_within(2..30, 4);
106 hash[..4].copy_from_slice(&len.to_le_bytes());
107 hash
108 },
109 };
110 r[..8].copy_from_slice(&[id[0], hash[0], id[1], hash[1], id[2], hash[2], id[3], hash[3]]);
111 r[8..].copy_from_slice(&hash[4..27]);
112 r.into()
113 }
114}
115
116#[derive(Debug, Clone, Encode, Decode)]
117pub struct Service {
118 pub code_hash: CodeHash,
120 pub balance: Balance,
122 pub min_item_gas: UnsignedGas,
125 pub min_memo_gas: UnsignedGas,
128 pub bytes: u64,
130 pub items: u32,
132}
133
134impl From<Service> for ServiceInfo {
135 fn from(service: Service) -> Self {
136 ServiceInfo {
137 code_hash: service.code_hash,
138 balance: service.balance,
139 min_item_gas: service.min_item_gas,
140 min_memo_gas: service.min_memo_gas,
141 bytes: service.bytes,
142 items: service.items,
143 threshold: service.threshold(),
144 }
145 }
146}
147
148impl Service {
149 pub fn threshold(&self) -> Balance {
150 Self::deposit_required(self.items, self.bytes)
151 }
152 pub fn free(&self) -> Balance {
153 self.balance.saturating_sub(self.threshold())
154 }
155 pub fn deposit_required(items: u32, bytes: u64) -> u64 {
156 items as u64 * deposit_per_item() + bytes * deposit_per_byte() + deposit_per_account()
157 }
158}
159
160pub type AuthPool = BoundedVec<AuthorizerHash, AuthWindow>;
161pub type AuthPools = FixedVec<AuthPool, CoreCount>;
162pub type AuthQueues = FixedVec<AuthQueue, CoreCount>;
163
164#[derive(Debug, Encode, Decode, Eq, PartialEq, Clone)]
166pub struct BlockInfo {
167 pub hash: HeaderHash,
169 pub beefy_mmr: Mmr,
171 pub state_root: StateRootHash,
173 pub reported: VecMap<WorkPackageHash, SegmentTreeRoot>,
176}
177
178#[derive(Debug, Encode, Decode, Eq, PartialEq, Clone)]
179pub struct AvailabilityAssignment {
180 pub report: WorkReport,
182 pub report_slot: Slot,
184}
185
186#[derive(Clone, Encode, Decode, Debug, Eq, PartialEq, Default)]
187pub struct Privileges {
188 pub bless: ServiceId,
190 pub assign: ServiceId,
192 pub designate: ServiceId,
194 pub always_acc: VecMap<ServiceId, UnsignedGas>,
196}
197
198#[derive(Clone, Encode, Decode, Debug, Eq, PartialEq, Default)]
199pub struct Disputes {
200 pub good: VecSet<WorkReportHash>,
202 pub bad: VecSet<WorkReportHash>,
204 pub wonky: VecSet<WorkReportHash>,
206 pub offenders: VecSet<super::ed25519::Public>,
209}
210
211#[derive(Clone, Encode, Decode, Debug, Eq, PartialEq, Default)]
212pub struct ValActivityRecord {
213 pub blocks: u32,
215 pub tickets: u32,
217 pub preimages: u32,
219 pub preimages_size: u32,
221 pub guarantees: u32,
223 pub assurances: u32,
225}
226
227#[derive(Clone, Encode, Decode, Debug, Eq, PartialEq, Default)]
228pub struct ServiceActivityRecord {
229 #[codec(compact)]
231 pub provided_count: u16,
232 #[codec(compact)]
234 pub provided_size: u32,
235 #[codec(compact)]
237 pub refinement_count: u32,
238 #[codec(compact)]
240 pub refinement_gas_used: UnsignedGas,
241 #[codec(compact)]
243 pub imports: u32,
244 #[codec(compact)]
246 pub exports: u32,
247 #[codec(compact)]
249 pub extrinsic_size: u32,
250 #[codec(compact)]
252 pub extrinsic_count: u32,
253 #[codec(compact)]
255 pub accumulate_count: u32,
256 #[codec(compact)]
258 pub accumulate_gas_used: UnsignedGas,
259 #[codec(compact)]
261 pub on_transfers_count: u32,
262 #[codec(compact)]
264 pub on_transfers_gas_used: UnsignedGas,
265}
266
267#[derive(Clone, Encode, Decode, Debug, Eq, PartialEq, Default)]
268pub struct CoreActivityRecord {
269 #[codec(compact)]
274 pub da_load: u32,
275 #[codec(compact)]
277 pub popularity: u16,
278 #[codec(compact)]
280 pub imports: u16,
281 #[codec(compact)]
283 pub exports: u16,
284 #[codec(compact)]
286 pub extrinsic_size: u32,
287 #[codec(compact)]
289 pub extrinsic_count: u16,
290 #[codec(compact)]
292 pub bundle_size: u32,
293 #[codec(compact)]
296 pub gas_used: UnsignedGas,
297}
298
299pub type ValidatorsStats = FixedVec<ValActivityRecord, jam_types::ValCount>;
300pub type CoresStats = FixedVec<CoreActivityRecord, CoreCount>;
301pub type ServicesStats = VecMap<ServiceId, ServiceActivityRecord>;
302
303#[derive(Clone, Encode, Decode, Debug, Eq, PartialEq, Default)]
304pub struct Statistics {
305 pub vals_curr: ValidatorsStats,
306 pub vals_last: ValidatorsStats,
307 pub cores: CoresStats,
308 pub services: ServicesStats,
309}
310
311impl Statistics {
312 pub fn reset(&mut self) {
314 self.cores = Default::default();
315 self.services = Default::default();
316 }
317}
318
319pub type EntropyBuffer = FixedVec<Entropy, ConstU32<4>>;
324
325pub type RecentBlocks = BoundedVec<BlockInfo, RecentBlockCount>;
326
327pub type AvailabilityAssignments = FixedVec<Option<AvailabilityAssignment>, CoreCount>;
328
329#[derive(Clone, Encode, Decode, Debug, Eq, PartialEq)]
330pub struct ReadyRecord {
331 pub report: WorkReport,
332 pub deps: VecSet<WorkPackageHash>,
333}
334pub type ReadyQueue = FixedVec<Vec<ReadyRecord>, EpochPeriod>;
335pub type Accumulated = FixedVec<Vec<WorkPackageHash>, EpochPeriod>;