//! Implements support for the paint_system module. use crate::{ codec::Encoded, error::Error, metadata::MetadataError, paint::{ balances::Balances, ModuleCalls, }, Client, Valid, XtBuilder, }; use futures::future::{ self, Future, }; use parity_scale_codec::Codec; use runtime_primitives::traits::{ Bounded, CheckEqual, Hash, Header, IdentifyAccount, MaybeDisplay, MaybeSerialize, MaybeSerializeDeserialize, Member, SimpleArithmetic, SimpleBitOps, StaticLookup, Verify, }; use runtime_support::Parameter; use serde::de::DeserializeOwned; use substrate_primitives::Pair; use std::fmt::Debug; /// The subset of the `paint::Trait` that a client must implement. pub trait System: 'static + Eq + Clone + Debug { /// Account index (aka nonce) type. This stores the number of previous /// transactions associated with a sender account. type Index: Parameter + Member + MaybeSerialize + Debug + Default + MaybeDisplay + SimpleArithmetic + Copy; /// The block number type used by the runtime. type BlockNumber: Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + SimpleArithmetic + Default + Bounded + Copy + std::hash::Hash; /// The output of the `Hashing` function. type Hash: Parameter + Member + MaybeSerializeDeserialize + Debug + MaybeDisplay + SimpleBitOps + Default + Copy + CheckEqual + std::hash::Hash + AsRef<[u8]> + AsMut<[u8]>; /// The hashing system (algorithm) being used in the runtime (e.g. Blake2). type Hashing: Hash; /// The user account identifier type for the runtime. type AccountId: Parameter + Member + MaybeSerialize + Debug + MaybeDisplay + Ord + Default; /// The address type. This instead of `::Source`. type Address: Codec + Clone + PartialEq + Debug; /// The block header. type Header: Parameter + Header + DeserializeOwned; } /// Blanket impl for using existing runtime types impl System for T where ::Header: serde::de::DeserializeOwned, { type Index = T::Index; type BlockNumber = T::BlockNumber; type Hash = T::Hash; type Hashing = T::Hashing; type AccountId = T::AccountId; type Address = ::Source; type Header = T::Header; } /// The System extension trait for the Client. pub trait SystemStore { /// System type. type System: System; /// Returns the account nonce for an account_id. fn account_nonce( &self, account_id: ::AccountId, ) -> Box::Index, Error = Error> + Send>; } impl SystemStore for Client { type System = T; fn account_nonce( &self, account_id: ::AccountId, ) -> Box::Index, Error = Error> + Send> { let account_nonce_map = || { Ok(self .metadata .module("System")? .storage("AccountNonce")? .get_map()?) }; let map = match account_nonce_map() { Ok(map) => map, Err(err) => return Box::new(future::err(err)), }; Box::new(self.fetch_or(map.key(account_id), map.default())) } } /// The System extension trait for the XtBuilder. pub trait SystemXt { /// System type. type System: System; /// Keypair type type Pair: Pair; /// Signature type type Signature: Verify; /// Create a call for the paint system module fn system(&self, f: F) -> XtBuilder where F: FnOnce( ModuleCalls, ) -> Result; } impl SystemXt for XtBuilder where P: Pair, S: Verify, S::Signer: From + IdentifyAccount, { type System = T; type Pair = P; type Signature = S; fn system(&self, f: F) -> XtBuilder where F: FnOnce( ModuleCalls, ) -> Result, { self.set_call("System", f) } } impl ModuleCalls where P: Pair, { /// Sets the new code. pub fn set_code(&self, code: Vec) -> Result { self.module.call("set_code", code) } } /// Event for the System module. #[derive(Clone, Debug, parity_scale_codec::Decode)] pub enum SystemEvent { /// An extrinsic completed successfully. ExtrinsicSuccess, /// An extrinsic failed. ExtrinsicFailed(runtime_primitives::DispatchError), }