1use crate::{
21 codec::{Codec, Decode, Encode, MaxEncodedLen},
22 generic,
23 scale_info::TypeInfo,
24 traits::{
25 self, Applyable, BlakeTwo256, Checkable, DispatchInfoOf, Dispatchable, OpaqueKeys,
26 PostDispatchInfoOf, SignaturePayload, SignedExtension, ValidateUnsigned,
27 },
28 transaction_validity::{TransactionSource, TransactionValidity, TransactionValidityError},
29 ApplyExtrinsicResultWithInfo, KeyTypeId,
30};
31use serde::{de::Error as DeError, Deserialize, Deserializer, Serialize, Serializer};
32use sp_core::{
33 crypto::{key_types, ByteArray, CryptoType, Dummy},
34 U256,
35};
36pub use sp_core::{sr25519, H256};
37use std::{
38 cell::RefCell,
39 fmt::{self, Debug},
40 ops::Deref,
41};
42
43#[derive(
50 Default,
51 PartialEq,
52 Eq,
53 Clone,
54 Encode,
55 Decode,
56 Debug,
57 Hash,
58 Serialize,
59 Deserialize,
60 PartialOrd,
61 Ord,
62 MaxEncodedLen,
63 TypeInfo,
64)]
65pub struct UintAuthorityId(pub u64);
66
67impl From<u64> for UintAuthorityId {
68 fn from(id: u64) -> Self {
69 UintAuthorityId(id)
70 }
71}
72
73impl From<UintAuthorityId> for u64 {
74 fn from(id: UintAuthorityId) -> u64 {
75 id.0
76 }
77}
78
79impl UintAuthorityId {
80 pub fn to_public_key<T: ByteArray>(&self) -> T {
82 let bytes: [u8; 32] = U256::from(self.0).into();
83 T::from_slice(&bytes).unwrap()
84 }
85}
86
87impl CryptoType for UintAuthorityId {
88 type Pair = Dummy;
89}
90
91impl AsRef<[u8]> for UintAuthorityId {
92 fn as_ref(&self) -> &[u8] {
93 unsafe {
96 std::slice::from_raw_parts(
97 &self.0 as *const u64 as *const _,
98 std::mem::size_of::<u64>(),
99 )
100 }
101 }
102}
103
104thread_local! {
105 static ALL_KEYS: RefCell<Vec<UintAuthorityId>> = RefCell::new(vec![]);
107}
108
109impl UintAuthorityId {
110 pub fn set_all_keys<T: Into<UintAuthorityId>>(keys: impl IntoIterator<Item = T>) {
112 ALL_KEYS.with(|l| *l.borrow_mut() = keys.into_iter().map(Into::into).collect())
113 }
114}
115
116impl sp_application_crypto::RuntimeAppPublic for UintAuthorityId {
117 const ID: KeyTypeId = key_types::DUMMY;
118
119 type Signature = TestSignature;
120
121 fn all() -> Vec<Self> {
122 ALL_KEYS.with(|l| l.borrow().clone())
123 }
124
125 fn generate_pair(_: Option<Vec<u8>>) -> Self {
126 use rand::RngCore;
127 UintAuthorityId(rand::thread_rng().next_u64())
128 }
129
130 fn sign<M: AsRef<[u8]>>(&self, msg: &M) -> Option<Self::Signature> {
131 Some(TestSignature(self.0, msg.as_ref().to_vec()))
132 }
133
134 fn verify<M: AsRef<[u8]>>(&self, msg: &M, signature: &Self::Signature) -> bool {
135 traits::Verify::verify(signature, msg.as_ref(), &self.0)
136 }
137
138 fn to_raw_vec(&self) -> Vec<u8> {
139 AsRef::<[u8]>::as_ref(self).to_vec()
140 }
141}
142
143impl OpaqueKeys for UintAuthorityId {
144 type KeyTypeIdProviders = ();
145
146 fn key_ids() -> &'static [KeyTypeId] {
147 &[key_types::DUMMY]
148 }
149
150 fn get_raw(&self, _: KeyTypeId) -> &[u8] {
151 self.as_ref()
152 }
153
154 fn get<T: Decode>(&self, _: KeyTypeId) -> Option<T> {
155 self.using_encoded(|mut x| T::decode(&mut x)).ok()
156 }
157}
158
159impl traits::IdentifyAccount for UintAuthorityId {
160 type AccountId = u64;
161
162 fn into_account(self) -> Self::AccountId {
163 self.0
164 }
165}
166
167#[derive(Eq, PartialEq, Clone, Debug, Hash, Serialize, Deserialize, Encode, Decode, TypeInfo)]
169pub struct TestSignature(pub u64, pub Vec<u8>);
170
171impl traits::Verify for TestSignature {
172 type Signer = UintAuthorityId;
173
174 fn verify<L: traits::Lazy<[u8]>>(&self, mut msg: L, signer: &u64) -> bool {
175 signer == &self.0 && msg.get() == &self.1[..]
176 }
177}
178
179pub type DigestItem = generic::DigestItem;
181
182pub type Digest = generic::Digest;
184
185pub type Header = generic::Header<u64, BlakeTwo256>;
187
188impl Header {
189 pub fn new_from_number(number: <Self as traits::Header>::Number) -> Self {
191 Self {
192 number,
193 extrinsics_root: Default::default(),
194 state_root: Default::default(),
195 parent_hash: Default::default(),
196 digest: Default::default(),
197 }
198 }
199}
200
201#[derive(PartialEq, Eq, Clone, Debug, Encode, Decode)]
203pub struct ExtrinsicWrapper<Xt>(Xt);
204
205impl<Xt> traits::Extrinsic for ExtrinsicWrapper<Xt> {
206 type Call = ();
207 type SignaturePayload = ();
208
209 fn is_signed(&self) -> Option<bool> {
210 None
211 }
212}
213
214impl<Xt: Encode> serde::Serialize for ExtrinsicWrapper<Xt> {
215 fn serialize<S>(&self, seq: S) -> Result<S::Ok, S::Error>
216 where
217 S: ::serde::Serializer,
218 {
219 self.using_encoded(|bytes| seq.serialize_bytes(bytes))
220 }
221}
222
223impl<Xt> From<Xt> for ExtrinsicWrapper<Xt> {
224 fn from(xt: Xt) -> Self {
225 ExtrinsicWrapper(xt)
226 }
227}
228
229impl<Xt> Deref for ExtrinsicWrapper<Xt> {
230 type Target = Xt;
231
232 fn deref(&self) -> &Self::Target {
233 &self.0
234 }
235}
236
237#[derive(PartialEq, Eq, Clone, Serialize, Debug, Encode, Decode, TypeInfo)]
239pub struct Block<Xt> {
240 pub header: Header,
242 pub extrinsics: Vec<Xt>,
244}
245
246impl<Xt> traits::HeaderProvider for Block<Xt> {
247 type HeaderT = Header;
248}
249
250impl<
251 Xt: 'static + Codec + Sized + Send + Sync + Serialize + Clone + Eq + Debug + traits::Extrinsic,
252 > traits::Block for Block<Xt>
253{
254 type Extrinsic = Xt;
255 type Header = Header;
256 type Hash = <Header as traits::Header>::Hash;
257
258 fn header(&self) -> &Self::Header {
259 &self.header
260 }
261 fn extrinsics(&self) -> &[Self::Extrinsic] {
262 &self.extrinsics[..]
263 }
264 fn deconstruct(self) -> (Self::Header, Vec<Self::Extrinsic>) {
265 (self.header, self.extrinsics)
266 }
267 fn new(header: Self::Header, extrinsics: Vec<Self::Extrinsic>) -> Self {
268 Block { header, extrinsics }
269 }
270 fn encode_from(header: &Self::Header, extrinsics: &[Self::Extrinsic]) -> Vec<u8> {
271 (header, extrinsics).encode()
272 }
273}
274
275impl<'a, Xt> Deserialize<'a> for Block<Xt>
276where
277 Block<Xt>: Decode,
278{
279 fn deserialize<D: Deserializer<'a>>(de: D) -> Result<Self, D::Error> {
280 let r = <Vec<u8>>::deserialize(de)?;
281 Decode::decode(&mut &r[..])
282 .map_err(|e| DeError::custom(format!("Invalid value passed into decode: {}", e)))
283 }
284}
285
286type TxSignaturePayload<Extra> = (u64, Extra);
288
289impl<Extra: TypeInfo> SignaturePayload for TxSignaturePayload<Extra> {
290 type SignatureAddress = u64;
291 type Signature = ();
292 type SignatureExtra = Extra;
293}
294
295#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo)]
300pub struct TestXt<Call, Extra> {
301 pub signature: Option<TxSignaturePayload<Extra>>,
303 pub call: Call,
305}
306
307impl<Call, Extra> TestXt<Call, Extra> {
308 pub fn new(call: Call, signature: Option<(u64, Extra)>) -> Self {
310 Self { call, signature }
311 }
312}
313
314impl<Call, Extra> Serialize for TestXt<Call, Extra>
315where
316 TestXt<Call, Extra>: Encode,
317{
318 fn serialize<S>(&self, seq: S) -> Result<S::Ok, S::Error>
319 where
320 S: Serializer,
321 {
322 self.using_encoded(|bytes| seq.serialize_bytes(bytes))
323 }
324}
325
326impl<Call, Extra> Debug for TestXt<Call, Extra> {
327 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
328 write!(f, "TestXt({:?}, ...)", self.signature.as_ref().map(|x| &x.0))
329 }
330}
331
332impl<Call: Codec + Sync + Send, Context, Extra> Checkable<Context> for TestXt<Call, Extra> {
333 type Checked = Self;
334 fn check(self, _: &Context) -> Result<Self::Checked, TransactionValidityError> {
335 Ok(self)
336 }
337
338 #[cfg(feature = "try-runtime")]
339 fn unchecked_into_checked_i_know_what_i_am_doing(
340 self,
341 _: &Context,
342 ) -> Result<Self::Checked, TransactionValidityError> {
343 unreachable!()
344 }
345}
346
347impl<Call: Codec + Sync + Send + TypeInfo, Extra: TypeInfo> traits::Extrinsic
348 for TestXt<Call, Extra>
349{
350 type Call = Call;
351 type SignaturePayload = TxSignaturePayload<Extra>;
352
353 fn is_signed(&self) -> Option<bool> {
354 Some(self.signature.is_some())
355 }
356
357 fn new(c: Call, sig: Option<Self::SignaturePayload>) -> Option<Self> {
358 Some(TestXt { signature: sig, call: c })
359 }
360}
361
362impl<Call, Extra> traits::ExtrinsicMetadata for TestXt<Call, Extra>
363where
364 Call: Codec + Sync + Send,
365 Extra: SignedExtension<AccountId = u64, Call = Call>,
366{
367 type SignedExtensions = Extra;
368 const VERSION: u8 = 0u8;
369}
370
371impl<Origin, Call, Extra> Applyable for TestXt<Call, Extra>
372where
373 Call: 'static
374 + Sized
375 + Send
376 + Sync
377 + Clone
378 + Eq
379 + Codec
380 + Debug
381 + Dispatchable<RuntimeOrigin = Origin>,
382 Extra: SignedExtension<AccountId = u64, Call = Call>,
383 Origin: From<Option<u64>>,
384{
385 type Call = Call;
386
387 fn validate<U: ValidateUnsigned<Call = Self::Call>>(
389 &self,
390 source: TransactionSource,
391 info: &DispatchInfoOf<Self::Call>,
392 len: usize,
393 ) -> TransactionValidity {
394 if let Some((ref id, ref extra)) = self.signature {
395 Extra::validate(extra, id, &self.call, info, len)
396 } else {
397 let valid = Extra::validate_unsigned(&self.call, info, len)?;
398 let unsigned_validation = U::validate_unsigned(source, &self.call)?;
399 Ok(valid.combine_with(unsigned_validation))
400 }
401 }
402
403 fn apply<U: ValidateUnsigned<Call = Self::Call>>(
406 self,
407 info: &DispatchInfoOf<Self::Call>,
408 len: usize,
409 ) -> ApplyExtrinsicResultWithInfo<PostDispatchInfoOf<Self::Call>> {
410 let maybe_who = if let Some((who, extra)) = self.signature {
411 Extra::pre_dispatch(extra, &who, &self.call, info, len)?;
412 Some(who)
413 } else {
414 Extra::pre_dispatch_unsigned(&self.call, info, len)?;
415 U::pre_dispatch(&self.call)?;
416 None
417 };
418
419 Ok(self.call.dispatch(maybe_who.into()))
420 }
421}