1use crate::{Address, Digest, ToDigest, ValidatorsVec};
7use alloc::vec::Vec;
8use alloy_primitives::U256 as AlloyU256;
9use gear_core::message::{ReplyCode, ReplyDetails, StoredMessage, SuccessReplyReason};
10use gprimitives::{ActorId, CodeId, H256, MessageId, U256};
11use parity_scale_codec::{Decode, Encode};
12use scale_info::TypeInfo;
13use sha3::Digest as _;
14
15pub const COMPUTATION_THRESHOLD: u64 = 2_500_000_000;
17pub const WVARA_PER_SECOND: u128 = 10_000_000_000_000;
18
19pub const CHUNK_PROCESSING_GAS_LIMIT: u64 = 1_000_000_000_000;
21pub const INJECTED_MESSAGE_PANIC_GAS_CHARGE_THRESHOLD: u64 = 1_000_000_000;
23
24pub const MAX_BLOCK_GAS_LIMIT: u64 = 9_000_000_000_000;
26
27pub const CANONICAL_QUARANTINE: u8 = 16;
29
30#[derive(Clone, Debug, Default, Encode, Decode, PartialEq, Eq)]
31pub struct AggregatedPublicKey {
32 pub x: U256,
33 pub y: U256,
34}
35
36#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq)]
37#[repr(u8)]
38pub enum SignatureType {
39 FROST,
40 ECDSA,
41}
42
43#[derive(Clone, Debug, Default, Encode, Decode, PartialEq, Eq)]
44pub struct AddressBook {
45 pub mirror: ActorId,
46 pub mirror_proxy: ActorId,
47 pub wrapped_vara: ActorId,
48}
49
50#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq)]
53pub struct ChainCommitment {
54 pub transitions: Vec<StateTransition>,
55 pub head: H256,
56 pub last_advanced_eth_block: H256,
57}
58
59impl ToDigest for ChainCommitment {
60 fn update_hasher(&self, hasher: &mut sha3::Keccak256) {
61 let ChainCommitment {
62 transitions,
63 head,
64 last_advanced_eth_block,
65 } = self;
66
67 hasher.update(transitions.to_digest());
68 hasher.update(head.0);
69 hasher.update(last_advanced_eth_block.0);
70 }
71}
72
73#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq)]
74pub struct CodeCommitment {
75 pub id: CodeId,
76 pub valid: bool,
77}
78
79impl ToDigest for CodeCommitment {
80 fn update_hasher(&self, hasher: &mut sha3::Keccak256) {
81 let Self { id, valid } = self;
83
84 hasher.update(id.into_bytes());
85 hasher.update([*valid as u8]);
86 }
87}
88
89#[derive(Clone, Debug, Default, Encode, Decode, PartialEq, Eq)]
90pub struct OperatorRewardsCommitment {
91 pub amount: U256,
92 pub root: H256,
93}
94
95impl ToDigest for OperatorRewardsCommitment {
96 fn update_hasher(&self, hasher: &mut sha3::Keccak256) {
97 let OperatorRewardsCommitment { amount, root } = self;
98
99 hasher.update(<[u8; 32]>::from(*amount));
100 hasher.update(root);
101 }
102}
103
104#[derive(Clone, Debug, Default, Encode, Decode, PartialEq, Eq)]
105pub struct StakerRewards {
106 pub vault: Address,
107 pub amount: U256,
108}
109
110#[derive(Clone, Debug, Default, Encode, Decode, PartialEq, Eq)]
111pub struct StakerRewardsCommitment {
112 pub distribution: Vec<StakerRewards>,
113 pub total_amount: U256,
114 pub token: Address,
115}
116
117impl ToDigest for StakerRewardsCommitment {
118 fn update_hasher(&self, hasher: &mut sha3::Keccak256) {
119 let StakerRewardsCommitment {
120 distribution,
121 total_amount,
122 token,
123 } = &self;
124
125 distribution
126 .iter()
127 .for_each(|StakerRewards { vault, amount }| {
128 hasher.update(vault);
129 hasher.update(<[u8; 32]>::from(*amount));
130 });
131
132 hasher.update(<[u8; 32]>::from(*total_amount));
133 hasher.update(token);
134 }
135}
136
137#[derive(Clone, Debug, Default, Encode, Decode, PartialEq, Eq)]
138pub struct RewardsCommitment {
139 pub operators: OperatorRewardsCommitment,
140 pub stakers: StakerRewardsCommitment,
141 pub timestamp: u64,
143}
144
145impl ToDigest for RewardsCommitment {
146 fn update_hasher(&self, hasher: &mut sha3::Keccak256) {
147 let RewardsCommitment {
148 operators,
149 stakers,
150 timestamp,
151 } = self;
152
153 hasher.update(operators.to_digest());
154 hasher.update(stakers.to_digest());
155 hasher.update(crate::u64_into_uint48_be_bytes_lossy(*timestamp));
156 }
157}
158
159#[derive(Clone, Debug, Default, Encode, Decode, PartialEq, Eq)]
161pub struct BatchCommitment {
162 pub block_hash: H256,
166
167 pub timestamp: u64,
170
171 pub previous_batch: Digest,
174
175 pub expiry: u8,
180
181 pub chain_commitment: Option<ChainCommitment>,
182 pub code_commitments: Vec<CodeCommitment>,
183 pub validators_commitment: Option<ValidatorsCommitment>,
184 pub rewards_commitment: Option<RewardsCommitment>,
185}
186
187impl ToDigest for BatchCommitment {
188 fn update_hasher(&self, hasher: &mut sha3::Keccak256) {
189 let Self {
191 block_hash,
192 timestamp,
193 previous_batch,
194 expiry,
195 chain_commitment,
196 code_commitments,
197 validators_commitment,
198 rewards_commitment,
199 } = self;
200
201 hasher.update(block_hash);
202 hasher.update(crate::u64_into_uint48_be_bytes_lossy(*timestamp));
203 hasher.update(previous_batch);
204 hasher.update(expiry.to_be_bytes());
205 hasher.update(chain_commitment.to_digest());
206 hasher.update(code_commitments.to_digest());
207 hasher.update(rewards_commitment.to_digest());
208 hasher.update(validators_commitment.to_digest());
209 }
210}
211
212#[derive(Clone, Debug, Default, Encode, Decode, PartialEq, Eq)]
213pub struct Timelines {
214 pub era: u64,
215 pub election: u64,
216 pub validation_delay: u64,
217}
218
219#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq)]
220pub struct ValidatorsCommitment {
221 pub has_aggregated_public_key: bool,
223 pub aggregated_public_key: AggregatedPublicKey,
224 pub verifiable_secret_sharing_commitment: Vec<u8>,
225 pub validators: ValidatorsVec,
226 pub era_index: u64,
227}
228
229impl ToDigest for ValidatorsCommitment {
230 fn update_hasher(&self, hasher: &mut sha3::Keccak256) {
231 let ValidatorsCommitment {
232 has_aggregated_public_key,
233 aggregated_public_key,
234 verifiable_secret_sharing_commitment: _, validators,
236 era_index,
237 } = self;
238
239 hasher.update([*has_aggregated_public_key as u8]);
240 hasher.update(<[u8; 32]>::from(aggregated_public_key.x));
241 hasher.update(<[u8; 32]>::from(aggregated_public_key.y));
242 hasher.update(
243 validators
244 .iter()
245 .flat_map(|v| {
246 let mut bytes = [0u8; 32];
248 bytes[12..32].copy_from_slice(&v.0);
249 bytes.into_iter()
250 })
251 .collect::<Vec<u8>>(),
252 );
253
254 let bytes = AlloyU256::from(*era_index).to_be_bytes::<32>();
255 hasher.update(bytes);
256 }
257}
258
259#[derive(Clone, Copy, Debug, Default, Encode, Decode, PartialEq, Eq)]
260pub enum CodeState {
261 #[default]
262 Unknown,
263 ValidationRequested,
264 Validated,
265}
266
267impl From<u8> for CodeState {
268 fn from(value: u8) -> Self {
269 match value {
270 0 => Self::Unknown,
271 1 => Self::ValidationRequested,
272 2 => Self::Validated,
273 _ => Self::Unknown,
275 }
276 }
277}
278
279#[derive(Clone, Debug, Default, Encode, Decode, PartialEq, Eq)]
280pub struct CommittedBlockInfo {
281 pub hash: H256,
282 pub timestamp: u64,
284}
285
286#[derive(Clone, Debug, Default, Encode, Decode, PartialEq, Eq)]
287pub struct ComputationSettings {
288 pub threshold: u64,
289 pub wvara_per_second: u128,
290}
291
292#[derive(Clone, Debug, Default, Encode, Decode, TypeInfo, PartialEq, Eq, Hash)]
293#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
294pub struct Message {
295 pub id: MessageId,
296 pub destination: ActorId,
297 pub payload: Vec<u8>,
298 pub value: u128,
299 pub reply_details: Option<ReplyDetails>,
300 pub call: bool,
301}
302
303impl ToDigest for Message {
304 fn update_hasher(&self, hasher: &mut sha3::Keccak256) {
305 let Self {
307 id,
308 destination,
309 payload,
310 value,
311 reply_details,
312 call,
313 } = self;
314
315 let (reply_details_to, reply_details_code) =
316 reply_details.map(|d| d.into_parts()).unwrap_or((
317 MessageId::default(),
318 ReplyCode::Success(SuccessReplyReason::Auto),
319 ));
320
321 hasher.update(id);
322 hasher.update(destination.to_address_lossy());
323 hasher.update(payload);
324 hasher.update(value.to_be_bytes());
325 hasher.update(reply_details_to);
326 hasher.update(reply_details_code.to_bytes());
327 hasher.update([*call as u8]);
328 }
329}
330
331impl Message {
332 pub fn from_stored(value: StoredMessage, call: bool) -> Self {
333 let (id, _source, destination, payload, value, details) = value.into_parts();
334 Self {
335 id,
336 destination,
337 payload: payload.into_vec(),
338 value,
339 reply_details: details.and_then(|v| v.to_reply_details()),
340 call,
341 }
342 }
343}
344
345#[derive(Clone, Debug, Default, Encode, Decode, PartialEq, Eq)]
346pub struct ProtocolData {
347 pub programs_count: U256,
350 pub validated_codes_count: U256,
351}
352
353#[derive(Clone, Debug, Default, Encode, Decode, TypeInfo, PartialEq, Eq, Hash)]
354#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
355pub struct StateTransition {
356 pub actor_id: ActorId,
357 pub new_state_hash: H256,
358 pub exited: bool,
359 pub inheritor: ActorId,
360 pub value_to_receive: u128,
373 pub value_to_receive_negative_sign: bool,
374 pub value_claims: Vec<ValueClaim>,
375 pub messages: Vec<Message>,
376}
377
378impl ToDigest for StateTransition {
379 fn update_hasher(&self, hasher: &mut sha3::Keccak256) {
380 let Self {
382 actor_id,
383 new_state_hash,
384 exited,
385 inheritor,
386 value_to_receive,
387 value_to_receive_negative_sign,
388 value_claims,
389 messages,
390 } = self;
391
392 hasher.update(actor_id.to_address_lossy());
393 hasher.update(new_state_hash);
394 hasher.update([*exited as u8]);
395 hasher.update(inheritor.to_address_lossy());
396 hasher.update(value_to_receive.to_be_bytes());
397 hasher.update([*value_to_receive_negative_sign as u8]);
398 hasher.update(value_claims.to_digest());
399 hasher.update(messages.to_digest());
400 }
401}
402
403#[derive(Clone, Debug, Default, Encode, Decode, TypeInfo, PartialEq, Eq, Hash)]
404#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
405pub struct ValueClaim {
406 pub message_id: MessageId,
407 pub destination: ActorId,
408 pub value: u128,
409}
410
411impl ToDigest for ValueClaim {
412 fn update_hasher(&self, hasher: &mut sha3::Keccak256) {
413 let ValueClaim {
414 message_id,
415 destination,
416 value,
417 } = self;
418
419 hasher.update(message_id);
420 hasher.update(destination.to_address_lossy());
421 hasher.update(value.to_be_bytes());
422 }
423}
424
425#[derive(
426 Clone,
427 Copy,
428 Debug,
429 Encode,
430 Decode,
431 PartialEq,
432 Eq,
433 Default,
434 PartialOrd,
435 Ord,
436 Hash,
437 derive_more::IsVariant,
438)]
439#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
440pub enum MessageType {
441 #[default]
442 Canonical,
443 Injected,
444}
445
446#[derive(Debug)]
447pub struct GenesisBlockInfo {
448 pub hash: H256,
449 pub number: u32,
450 pub timestamp: u64,
451}
452
453#[cfg(test)]
454mod tests {
455 use super::*;
456
457 #[test]
458 fn validators_commitment_accepts_raw_vss_commitment_bytes() {
459 let commitment = ValidatorsCommitment {
460 has_aggregated_public_key: false,
461 aggregated_public_key: AggregatedPublicKey::default(),
462 verifiable_secret_sharing_commitment: vec![],
463 validators: nonempty::nonempty![crate::Address::default()].into(),
464 era_index: 0,
465 };
466
467 assert!(commitment.verifiable_secret_sharing_commitment.is_empty());
468 }
469}