1use codec::{Decode, Encode};
2use scale_info::{
3 prelude::{fmt::Debug, vec::Vec},
4 TypeInfo,
5};
6
7pub type TargetId = [u8; 4];
8pub type EventSignature = Vec<u8>;
9pub type SideEffectName = Vec<u8>;
10type Bytes = Vec<u8>;
11
12#[derive(Clone, Eq, PartialEq, Encode, Default, Decode, Debug, TypeInfo)]
13pub struct SideEffect<AccountId, BlockNumber, BalanceOf> {
14 pub target: TargetId,
15 pub prize: BalanceOf,
16 pub ordered_at: BlockNumber,
17 pub encoded_action: Bytes,
18 pub encoded_args: Vec<Bytes>,
19 pub signature: Bytes,
20 pub enforce_executioner: Option<AccountId>,
21}
22
23#[cfg(feature = "runtime")]
24impl<
25 AccountId: Encode,
26 BlockNumber: Ord + Copy + sp_runtime::traits::Zero + Encode,
27 BalanceOf: Copy + sp_runtime::traits::Zero + Encode + Decode,
28 > SideEffect<AccountId, BlockNumber, BalanceOf>
29{
30 pub fn generate_id<Hasher: sp_core::Hasher>(&self) -> <Hasher as sp_core::Hasher>::Out {
31 Hasher::hash(Encode::encode(self).as_ref())
32 }
33
34 pub fn id_as_bytes<Hasher: sp_core::Hasher>(id: <Hasher as sp_core::Hasher>::Out) -> Bytes {
35 id.as_ref().to_vec()
36 }
37}
38
39#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo)]
40pub enum ConfirmationOutcome {
41 Success,
42 MisbehaviourMalformedValues {
43 key: Bytes,
44 expected: Bytes,
45 received: Bytes,
46 },
47 TimedOut,
48}
49
50impl Default for ConfirmationOutcome {
51 fn default() -> Self {
52 ConfirmationOutcome::Success
53 }
54}
55
56#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug, TypeInfo)]
57pub struct ConfirmedSideEffect<AccountId, BlockNumber, BalanceOf> {
58 pub err: Option<ConfirmationOutcome>,
59 pub output: Option<Bytes>,
60 pub encoded_effect: Bytes,
61 pub inclusion_proof: Option<Bytes>,
62 pub executioner: AccountId,
63 pub received_at: BlockNumber,
64 pub cost: Option<BalanceOf>,
65}
66
67#[derive(Clone, Eq, PartialEq, PartialOrd, Ord, Encode, Decode, Debug, TypeInfo)]
68pub enum SecurityLvl {
69 Dirty,
70 Optimistic,
71 Escrowed,
72}
73
74impl Default for SecurityLvl {
75 fn default() -> Self {
76 SecurityLvl::Dirty
77 }
78}
79
80#[derive(Debug, PartialEq)]
82pub enum Error {
83 HardeningDecodeError,
85 HardeningMissingConfirmationError,
87}
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92
93 use sp_core::crypto::AccountId32;
94
95 type BlockNumber = u64;
96 type BalanceOf = u128;
97 type AccountId = AccountId32;
98
99 #[test]
100 fn successfully_creates_empty_side_effect() {
101 let empty_side_effect = SideEffect::<AccountId, BlockNumber, BalanceOf> {
102 target: [0, 0, 0, 0],
103 prize: 0,
104 ordered_at: 0,
105 encoded_action: vec![],
106 encoded_args: vec![],
107 signature: vec![],
108 enforce_executioner: None,
109 };
110
111 assert_eq!(
112 empty_side_effect,
113 SideEffect {
114 target: [0, 0, 0, 0],
115 prize: 0,
116 ordered_at: 0,
117 encoded_action: vec![],
118 encoded_args: vec![],
119 signature: vec![],
120 enforce_executioner: None,
121 }
122 );
123 }
124
125 #[test]
126 fn successfully_encodes_transfer_full_side_effect_with_confirmation() {
127 let from: AccountId32 = AccountId32::new([1u8; 32]);
128 let to: AccountId32 = AccountId32::new([2u8; 32]);
129 let value: BalanceOf = 1u128;
130 let optional_insurance = 2u128;
131 let optional_reward = 3u128;
132
133 let tsfx_input = SideEffect::<AccountId, BlockNumber, BalanceOf> {
134 target: [0, 0, 0, 0],
135 prize: 0,
136 ordered_at: 0,
137 encoded_action: vec![],
138 encoded_args: vec![
139 from.encode(),
140 to.encode(),
141 value.encode(),
142 [optional_insurance.encode(), optional_reward.encode()].concat(),
143 ],
144 signature: vec![],
145 enforce_executioner: None,
146 };
147
148 assert_eq!(
149 tsfx_input,
150 SideEffect {
151 target: [0, 0, 0, 0],
152 prize: 0,
153 ordered_at: 0,
154 encoded_action: vec![],
155 encoded_args: vec![
156 vec![
157 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
158 1, 1, 1, 1, 1, 1, 1
159 ],
160 vec![
161 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
162 2, 2, 2, 2, 2, 2, 2
163 ],
164 vec![1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
165 vec![
166 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0,
167 0, 0, 0, 0, 0, 0, 0
168 ]
169 ],
170 signature: vec![],
171 enforce_executioner: None,
172 }
173 );
174 }
175
176 #[test]
177 fn successfully_defaults_side_effect_to_an_empty_one() {
178 let empty_side_effect = SideEffect::<u64, BlockNumber, BalanceOf> {
179 target: [0, 0, 0, 0],
180 prize: 0,
181 ordered_at: 0,
182 encoded_action: vec![],
183 encoded_args: vec![],
184 signature: vec![],
185 enforce_executioner: None,
186 };
187
188 assert_eq!(empty_side_effect, SideEffect::default(),);
189 }
190}