1#![warn(missing_docs)]
21#![cfg_attr(not(feature = "std"), no_std)]
22
23#![cfg_attr(feature = "bench", feature(test))]
25#[cfg(feature = "bench")] extern crate test;
26
27#[doc(hidden)]
28pub use codec;
29#[cfg(feature = "std")]
30#[doc(hidden)]
31pub use serde;
32#[doc(hidden)]
33pub use tetcore_std;
34
35#[doc(hidden)]
36pub use paste;
37
38#[doc(hidden)]
39pub use tet_application_crypto as app_crypto;
40
41#[cfg(feature = "std")]
42pub use tet_core::storage::{Storage, StorageChild};
43
44use tetcore_std::prelude::*;
45use tetcore_std::convert::TryFrom;
46use tet_core::{crypto::{self, Public}, ed25519, sr25519, ecdsa, hash::{H256, H512}};
47
48use codec::{Encode, Decode};
49
50pub mod curve;
51pub mod generic;
52pub mod offchain;
53#[cfg(feature = "std")]
54pub mod testing;
55pub mod traits;
56pub mod transaction_validity;
57pub mod random_number_generator;
58mod runtime_string;
59mod multiaddress;
60
61pub use crate::runtime_string::*;
62
63pub use multiaddress::MultiAddress;
65
66pub use generic::{DigestItem, Digest};
68
69pub use tet_core::{TypeId, crypto::{key_types, KeyTypeId, CryptoType, CryptoTypeId, AccountId32}};
71pub use tet_application_crypto::{RuntimeAppPublic, BoundToRuntimeAppPublic};
72
73pub use tet_core::RuntimeDebug;
75
76pub use arithmetic::{
78 PerThing, Perquintill, Perbill, Permill, Percent, PerU16, InnerOf, UpperOf,
79 Rational128, FixedI64, FixedI128, FixedU128, FixedPointNumber, FixedPointOperand,
80 traits::SaturatedConversion,
81};
82pub use arithmetic::helpers_128bit;
84pub use arithmetic::biguint;
86
87pub use random_number_generator::RandomNumberGenerator;
88
89pub use either::Either;
90
91pub type Justification = Vec<u8>;
99
100use traits::{Verify, Lazy};
101
102#[derive(Clone, Copy, Eq, PartialEq, Encode, Decode)]
104pub struct ModuleId(pub [u8; 8]);
105
106impl TypeId for ModuleId {
107 const TYPE_ID: [u8; 4] = *b"modl";
108}
109
110#[cfg(feature = "std")]
111pub use serde::{Serialize, Deserialize, de::DeserializeOwned};
112use crate::traits::IdentifyAccount;
113
114#[cfg(feature = "std")]
116pub trait BuildStorage {
117 fn build_storage(&self) -> Result<tet_core::storage::Storage, String> {
119 let mut storage = Default::default();
120 self.assimilate_storage(&mut storage)?;
121 Ok(storage)
122 }
123 fn assimilate_storage(
125 &self,
126 storage: &mut tet_core::storage::Storage,
127 ) -> Result<(), String>;
128}
129
130#[cfg(feature = "std")]
132pub trait BuildModuleGenesisStorage<T, I>: Sized {
133 fn build_module_genesis_storage(
135 &self,
136 storage: &mut tet_core::storage::Storage,
137 ) -> Result<(), String>;
138}
139
140#[cfg(feature = "std")]
141impl BuildStorage for tet_core::storage::Storage {
142 fn assimilate_storage(
143 &self,
144 storage: &mut tet_core::storage::Storage,
145 )-> Result<(), String> {
146 storage.top.extend(self.top.iter().map(|(k, v)| (k.clone(), v.clone())));
147 for (k, other_map) in self.children_default.iter() {
148 let k = k.clone();
149 if let Some(map) = storage.children_default.get_mut(&k) {
150 map.data.extend(other_map.data.iter().map(|(k, v)| (k.clone(), v.clone())));
151 if !map.child_info.try_update(&other_map.child_info) {
152 return Err("Incompatible child info update".to_string());
153 }
154 } else {
155 storage.children_default.insert(k, other_map.clone());
156 }
157 }
158 Ok(())
159 }
160}
161
162#[cfg(feature = "std")]
163impl BuildStorage for () {
164 fn assimilate_storage(
165 &self,
166 _: &mut tet_core::storage::Storage,
167 ) -> Result<(), String> {
168 Err("`assimilate_storage` not implemented for `()`".into())
169 }
170}
171
172pub type ConsensusEngineId = [u8; 4];
174
175#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
177#[derive(Eq, PartialEq, Clone, Encode, Decode, RuntimeDebug)]
178pub enum MultiSignature {
179 Ed25519(ed25519::Signature),
181 Sr25519(sr25519::Signature),
183 Ecdsa(ecdsa::Signature),
185}
186
187impl From<ed25519::Signature> for MultiSignature {
188 fn from(x: ed25519::Signature) -> Self {
189 MultiSignature::Ed25519(x)
190 }
191}
192
193impl TryFrom<MultiSignature> for ed25519::Signature {
194 type Error = ();
195 fn try_from(m: MultiSignature) -> Result<Self, Self::Error> {
196 if let MultiSignature::Ed25519(x) = m { Ok(x) } else { Err(()) }
197 }
198}
199
200impl From<sr25519::Signature> for MultiSignature {
201 fn from(x: sr25519::Signature) -> Self {
202 MultiSignature::Sr25519(x)
203 }
204}
205
206impl TryFrom<MultiSignature> for sr25519::Signature {
207 type Error = ();
208 fn try_from(m: MultiSignature) -> Result<Self, Self::Error> {
209 if let MultiSignature::Sr25519(x) = m { Ok(x) } else { Err(()) }
210 }
211}
212
213impl From<ecdsa::Signature> for MultiSignature {
214 fn from(x: ecdsa::Signature) -> Self {
215 MultiSignature::Ecdsa(x)
216 }
217}
218
219impl TryFrom<MultiSignature> for ecdsa::Signature {
220 type Error = ();
221 fn try_from(m: MultiSignature) -> Result<Self, Self::Error> {
222 if let MultiSignature::Ecdsa(x) = m { Ok(x) } else { Err(()) }
223 }
224}
225
226impl Default for MultiSignature {
227 fn default() -> Self {
228 MultiSignature::Ed25519(Default::default())
229 }
230}
231
232#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Encode, Decode, RuntimeDebug)]
234#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
235pub enum MultiSigner {
236 Ed25519(ed25519::Public),
238 Sr25519(sr25519::Public),
240 Ecdsa(ecdsa::Public),
242}
243
244impl Default for MultiSigner {
245 fn default() -> Self {
246 MultiSigner::Ed25519(Default::default())
247 }
248}
249
250impl<T: Into<H256>> crypto::UncheckedFrom<T> for MultiSigner {
253 fn unchecked_from(x: T) -> Self {
254 ed25519::Public::unchecked_from(x.into()).into()
255 }
256}
257
258impl AsRef<[u8]> for MultiSigner {
259 fn as_ref(&self) -> &[u8] {
260 match *self {
261 MultiSigner::Ed25519(ref who) => who.as_ref(),
262 MultiSigner::Sr25519(ref who) => who.as_ref(),
263 MultiSigner::Ecdsa(ref who) => who.as_ref(),
264 }
265 }
266}
267
268impl traits::IdentifyAccount for MultiSigner {
269 type AccountId = AccountId32;
270 fn into_account(self) -> AccountId32 {
271 match self {
272 MultiSigner::Ed25519(who) => <[u8; 32]>::from(who).into(),
273 MultiSigner::Sr25519(who) => <[u8; 32]>::from(who).into(),
274 MultiSigner::Ecdsa(who) => tet_io::hashing::blake2_256(&who.as_ref()[..]).into(),
275 }
276 }
277}
278
279impl From<ed25519::Public> for MultiSigner {
280 fn from(x: ed25519::Public) -> Self {
281 MultiSigner::Ed25519(x)
282 }
283}
284
285impl TryFrom<MultiSigner> for ed25519::Public {
286 type Error = ();
287 fn try_from(m: MultiSigner) -> Result<Self, Self::Error> {
288 if let MultiSigner::Ed25519(x) = m { Ok(x) } else { Err(()) }
289 }
290}
291
292impl From<sr25519::Public> for MultiSigner {
293 fn from(x: sr25519::Public) -> Self {
294 MultiSigner::Sr25519(x)
295 }
296}
297
298impl TryFrom<MultiSigner> for sr25519::Public {
299 type Error = ();
300 fn try_from(m: MultiSigner) -> Result<Self, Self::Error> {
301 if let MultiSigner::Sr25519(x) = m { Ok(x) } else { Err(()) }
302 }
303}
304
305impl From<ecdsa::Public> for MultiSigner {
306 fn from(x: ecdsa::Public) -> Self {
307 MultiSigner::Ecdsa(x)
308 }
309}
310
311impl TryFrom<MultiSigner> for ecdsa::Public {
312 type Error = ();
313 fn try_from(m: MultiSigner) -> Result<Self, Self::Error> {
314 if let MultiSigner::Ecdsa(x) = m { Ok(x) } else { Err(()) }
315 }
316}
317
318#[cfg(feature = "std")]
319impl std::fmt::Display for MultiSigner {
320 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
321 match *self {
322 MultiSigner::Ed25519(ref who) => write!(fmt, "ed25519: {}", who),
323 MultiSigner::Sr25519(ref who) => write!(fmt, "sr25519: {}", who),
324 MultiSigner::Ecdsa(ref who) => write!(fmt, "ecdsa: {}", who),
325 }
326 }
327}
328
329impl Verify for MultiSignature {
330 type Signer = MultiSigner;
331 fn verify<L: Lazy<[u8]>>(&self, mut msg: L, signer: &AccountId32) -> bool {
332 match (self, signer) {
333 (MultiSignature::Ed25519(ref sig), who) => sig.verify(msg, &ed25519::Public::from_slice(who.as_ref())),
334 (MultiSignature::Sr25519(ref sig), who) => sig.verify(msg, &sr25519::Public::from_slice(who.as_ref())),
335 (MultiSignature::Ecdsa(ref sig), who) => {
336 let m = tet_io::hashing::blake2_256(msg.get());
337 match tet_io::crypto::secp256k1_ecdsa_recover_compressed(sig.as_ref(), &m) {
338 Ok(pubkey) =>
339 &tet_io::hashing::blake2_256(pubkey.as_ref())
340 == <dyn AsRef<[u8; 32]>>::as_ref(who),
341 _ => false,
342 }
343 }
344 }
345 }
346}
347
348#[derive(Eq, PartialEq, Clone, Default, Encode, Decode, RuntimeDebug)]
350#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
351pub struct AnySignature(H512);
352
353impl Verify for AnySignature {
354 type Signer = sr25519::Public;
355 fn verify<L: Lazy<[u8]>>(&self, mut msg: L, signer: &sr25519::Public) -> bool {
356 let msg = msg.get();
357 sr25519::Signature::try_from(self.0.as_fixed_bytes().as_ref())
358 .map(|s| s.verify(msg, signer))
359 .unwrap_or(false)
360 || ed25519::Signature::try_from(self.0.as_fixed_bytes().as_ref())
361 .map(|s| s.verify(msg, &ed25519::Public::from_slice(signer.as_ref())))
362 .unwrap_or(false)
363 }
364}
365
366impl From<sr25519::Signature> for AnySignature {
367 fn from(s: sr25519::Signature) -> Self {
368 AnySignature(s.into())
369 }
370}
371
372impl From<ed25519::Signature> for AnySignature {
373 fn from(s: ed25519::Signature) -> Self {
374 AnySignature(s.into())
375 }
376}
377
378impl From<DispatchError> for DispatchOutcome {
379 fn from(err: DispatchError) -> Self {
380 Err(err)
381 }
382}
383
384pub type DispatchResult = tetcore_std::result::Result<(), DispatchError>;
388
389pub type DispatchResultWithInfo<T> = tetcore_std::result::Result<T, DispatchErrorWithPostInfo<T>>;
392
393#[derive(Eq, PartialEq, Clone, Copy, Encode, Decode, RuntimeDebug)]
395#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
396pub enum DispatchError {
397 Other(#[codec(skip)] #[cfg_attr(feature = "std", serde(skip_deserializing))] &'static str),
399 CannotLookup,
401 BadOrigin,
403 Module {
405 index: u8,
407 error: u8,
409 #[codec(skip)]
411 #[cfg_attr(feature = "std", serde(skip_deserializing))]
412 message: Option<&'static str>,
413 },
414 ConsumerRemaining,
416 NoProviders,
418}
419
420#[derive(Eq, PartialEq, Clone, Copy, Encode, Decode, RuntimeDebug)]
423pub struct DispatchErrorWithPostInfo<Info> where
424 Info: Eq + PartialEq + Clone + Copy + Encode + Decode + traits::Printable
425{
426 pub post_info: Info,
428 pub error: DispatchError,
430}
431
432impl DispatchError {
433 pub fn stripped(self) -> Self {
435 match self {
436 DispatchError::Module { index, error, message: Some(_) }
437 => DispatchError::Module { index, error, message: None },
438 m => m,
439 }
440 }
441}
442
443impl<T, E> From<E> for DispatchErrorWithPostInfo<T> where
444 T: Eq + PartialEq + Clone + Copy + Encode + Decode + traits::Printable + Default,
445 E: Into<DispatchError>
446{
447 fn from(error: E) -> Self {
448 Self {
449 post_info: Default::default(),
450 error: error.into(),
451 }
452 }
453}
454
455impl From<crate::traits::LookupError> for DispatchError {
456 fn from(_: crate::traits::LookupError) -> Self {
457 Self::CannotLookup
458 }
459}
460
461impl From<crate::traits::BadOrigin> for DispatchError {
462 fn from(_: crate::traits::BadOrigin) -> Self {
463 Self::BadOrigin
464 }
465}
466
467impl From<crate::traits::StoredMapError> for DispatchError {
468 fn from(e: crate::traits::StoredMapError) -> Self {
469 match e {
470 crate::traits::StoredMapError::ConsumerRemaining => Self::ConsumerRemaining,
471 crate::traits::StoredMapError::NoProviders => Self::NoProviders,
472 }
473 }
474}
475
476impl From<&'static str> for DispatchError {
477 fn from(err: &'static str) -> DispatchError {
478 DispatchError::Other(err)
479 }
480}
481
482impl From<DispatchError> for &'static str {
483 fn from(err: DispatchError) -> &'static str {
484 match err {
485 DispatchError::Other(msg) => msg,
486 DispatchError::CannotLookup => "Cannot lookup",
487 DispatchError::BadOrigin => "Bad origin",
488 DispatchError::Module { message, .. } => message.unwrap_or("Unknown module error"),
489 DispatchError::ConsumerRemaining => "Consumer remaining",
490 DispatchError::NoProviders => "No providers",
491 }
492 }
493}
494
495impl<T> From<DispatchErrorWithPostInfo<T>> for &'static str where
496 T: Eq + PartialEq + Clone + Copy + Encode + Decode + traits::Printable
497{
498 fn from(err: DispatchErrorWithPostInfo<T>) -> &'static str {
499 err.error.into()
500 }
501}
502
503impl traits::Printable for DispatchError {
504 fn print(&self) {
505 "DispatchError".print();
506 match self {
507 Self::Other(err) => err.print(),
508 Self::CannotLookup => "Cannot lookup".print(),
509 Self::BadOrigin => "Bad origin".print(),
510 Self::Module { index, error, message } => {
511 index.print();
512 error.print();
513 if let Some(msg) = message {
514 msg.print();
515 }
516 }
517 Self::ConsumerRemaining => "Consumer remaining".print(),
518 Self::NoProviders => "No providers".print(),
519 }
520 }
521}
522
523impl<T> traits::Printable for DispatchErrorWithPostInfo<T> where
524 T: Eq + PartialEq + Clone + Copy + Encode + Decode + traits::Printable
525{
526 fn print(&self) {
527 self.error.print();
528 "PostInfo: ".print();
529 self.post_info.print();
530 }
531}
532
533pub type DispatchOutcome = Result<(), DispatchError>;
543
544pub type ApplyExtrinsicResult = Result<DispatchOutcome, transaction_validity::TransactionValidityError>;
563
564pub type ApplyExtrinsicResultWithInfo<T> =
566 Result<DispatchResultWithInfo<T>, transaction_validity::TransactionValidityError>;
567
568pub fn verify_encoded_lazy<V: Verify, T: codec::Encode>(
571 sig: &V,
572 item: &T,
573 signer: &<V::Signer as IdentifyAccount>::AccountId
574) -> bool {
575 struct LazyEncode<F> {
580 inner: F,
581 encoded: Option<Vec<u8>>,
582 }
583
584 impl<F: Fn() -> Vec<u8>> traits::Lazy<[u8]> for LazyEncode<F> {
585 fn get(&mut self) -> &[u8] {
586 self.encoded.get_or_insert_with(&self.inner).as_slice()
587 }
588 }
589
590 sig.verify(
591 LazyEncode { inner: || item.encode(), encoded: None },
592 signer,
593 )
594}
595
596#[macro_export]
614#[cfg(feature = "std")]
615macro_rules! assert_eq_error_rate {
616 ($x:expr, $y:expr, $error:expr $(,)?) => {
617 assert!(
618 ($x) >= (($y) - ($error)) && ($x) <= (($y) + ($error)),
619 "{:?} != {:?} (with error rate {:?})",
620 $x,
621 $y,
622 $error,
623 );
624 };
625}
626
627#[derive(PartialEq, Eq, Clone, Default, Encode, Decode)]
630pub struct OpaqueExtrinsic(Vec<u8>);
631
632impl OpaqueExtrinsic {
633 pub fn from_bytes(mut bytes: &[u8]) -> Result<Self, codec::Error> {
635 OpaqueExtrinsic::decode(&mut bytes)
636 }
637}
638
639#[cfg(feature = "std")]
640impl tetsy_util_mem::MallocSizeOf for OpaqueExtrinsic {
641 fn size_of(&self, ops: &mut tetsy_util_mem::MallocSizeOfOps) -> usize {
642 self.0.size_of(ops)
643 }
644}
645
646impl tetcore_std::fmt::Debug for OpaqueExtrinsic {
647 #[cfg(feature = "std")]
648 fn fmt(&self, fmt: &mut tetcore_std::fmt::Formatter) -> tetcore_std::fmt::Result {
649 write!(fmt, "{}", tet_core::hexdisplay::HexDisplay::from(&self.0))
650 }
651
652 #[cfg(not(feature = "std"))]
653 fn fmt(&self, _fmt: &mut tetcore_std::fmt::Formatter) -> tetcore_std::fmt::Result {
654 Ok(())
655 }
656}
657
658
659#[cfg(feature = "std")]
660impl ::serde::Serialize for OpaqueExtrinsic {
661 fn serialize<S>(&self, seq: S) -> Result<S::Ok, S::Error> where S: ::serde::Serializer {
662 codec::Encode::using_encoded(&self.0, |bytes| ::tet_core::bytes::serialize(bytes, seq))
663 }
664}
665
666#[cfg(feature = "std")]
667impl<'a> ::serde::Deserialize<'a> for OpaqueExtrinsic {
668 fn deserialize<D>(de: D) -> Result<Self, D::Error> where D: ::serde::Deserializer<'a> {
669 let r = ::tet_core::bytes::deserialize(de)?;
670 Decode::decode(&mut &r[..])
671 .map_err(|e| ::serde::de::Error::custom(format!("Decode error: {}", e)))
672 }
673}
674
675impl traits::Extrinsic for OpaqueExtrinsic {
676 type Call = ();
677 type SignaturePayload = ();
678}
679
680pub fn print(print: impl traits::Printable) {
682 print.print();
683}
684
685
686#[must_use = "`verify()` needs to be called to finish batch signature verification!"]
691pub struct SignatureBatching(bool);
692
693impl SignatureBatching {
694 pub fn start() -> Self {
696 tet_io::crypto::start_batch_verify();
697 SignatureBatching(false)
698 }
699
700 #[must_use]
702 pub fn verify(mut self) -> bool {
703 self.0 = true;
704 tet_io::crypto::finish_batch_verify()
705 }
706}
707
708impl Drop for SignatureBatching {
709 fn drop(&mut self) {
710 if !self.0 && !tetcore_std::thread::panicking() {
715 panic!("Signature verification has not been called before `SignatureBatching::drop`")
716 }
717 }
718}
719
720pub enum TransactionOutcome<R> {
722 Commit(R),
724 Rollback(R),
726}
727
728impl<R> TransactionOutcome<R> {
729 pub fn into_inner(self) -> R {
731 match self {
732 Self::Commit(r) => r,
733 Self::Rollback(r) => r,
734 }
735 }
736}
737
738#[cfg(test)]
739mod tests {
740 use super::*;
741 use codec::{Encode, Decode};
742 use tet_core::crypto::Pair;
743
744 #[test]
745 fn opaque_extrinsic_serialization() {
746 let ex = super::OpaqueExtrinsic(vec![1, 2, 3, 4]);
747 assert_eq!(serde_json::to_string(&ex).unwrap(), "\"0x1001020304\"".to_owned());
748 }
749
750 #[test]
751 fn dispatch_error_encoding() {
752 let error = DispatchError::Module {
753 index: 1,
754 error: 2,
755 message: Some("error message"),
756 };
757 let encoded = error.encode();
758 let decoded = DispatchError::decode(&mut &encoded[..]).unwrap();
759 assert_eq!(encoded, vec![3, 1, 2]);
760 assert_eq!(
761 decoded,
762 DispatchError::Module {
763 index: 1,
764 error: 2,
765 message: None,
766 },
767 );
768 }
769
770 #[test]
771 fn multi_signature_ecdsa_verify_works() {
772 let msg = &b"test-message"[..];
773 let (pair, _) = ecdsa::Pair::generate();
774
775 let signature = pair.sign(&msg);
776 assert!(ecdsa::Pair::verify(&signature, msg, &pair.public()));
777
778 let multi_sig = MultiSignature::from(signature);
779 let multi_signer = MultiSigner::from(pair.public());
780 assert!(multi_sig.verify(msg, &multi_signer.into_account()));
781
782 let multi_signer = MultiSigner::from(pair.public());
783 assert!(multi_sig.verify(msg, &multi_signer.into_account()));
784 }
785
786
787 #[test]
788 #[should_panic(expected = "Signature verification has not been called")]
789 fn batching_still_finishes_when_not_called_directly() {
790 let mut ext = tp_state_machine::BasicExternalities::default();
791 ext.register_extension(
792 tet_core::traits::TaskExecutorExt::new(tet_core::testing::TaskExecutor::new()),
793 );
794
795 ext.execute_with(|| {
796 let _batching = SignatureBatching::start();
797 tet_io::crypto::sr25519_verify(
798 &Default::default(),
799 &Vec::new(),
800 &Default::default(),
801 );
802 });
803 }
804
805 #[test]
806 #[should_panic(expected = "Hey, I'm an error")]
807 fn batching_does_not_panic_while_thread_is_already_panicking() {
808 let mut ext = tp_state_machine::BasicExternalities::default();
809 ext.register_extension(
810 tet_core::traits::TaskExecutorExt::new(tet_core::testing::TaskExecutor::new()),
811 );
812
813 ext.execute_with(|| {
814 let _batching = SignatureBatching::start();
815 panic!("Hey, I'm an error");
816 });
817 }
818}