diff --git a/src/events.rs b/src/events.rs index 69a1d8aa7e..c9300fdf68 100644 --- a/src/events.rs +++ b/src/events.rs @@ -50,8 +50,8 @@ use crate::{ /// Top level Event that can be produced by a substrate runtime #[derive(Debug)] -pub enum RuntimeEvent { - System(SystemEvent), +pub enum RuntimeEvent { + System(SystemEvent), Raw(RawEvent), } @@ -197,7 +197,7 @@ impl EventsDecoder { pub fn decode_events( &self, input: &mut &[u8], - ) -> Result, EventsError> { + ) -> Result)>, EventsError> { let compact_len = >::decode(input)?; let len = compact_len.0 as usize; diff --git a/src/frame/balances.rs b/src/frame/balances.rs index a37af971cb..c4a6538cc0 100644 --- a/src/frame/balances.rs +++ b/src/frame/balances.rs @@ -18,28 +18,19 @@ use std::{ fmt::Debug, - pin::Pin, }; - -use futures::future::{ - self, - Future, -}; - +use codec::{Encode, Decode}; use frame_support::Parameter; use sp_runtime::traits::{ MaybeSerialize, Member, - SimpleArithmetic, + AtLeast32Bit, }; - use crate::{ - error::Error, frame::{ system::System, Call, }, - Client, }; /// The subset of the `pallet_balances::Trait` that a client must implement. @@ -47,7 +38,7 @@ pub trait Balances: System { /// The balance of an account. type Balance: Parameter + Member - + SimpleArithmetic + + AtLeast32Bit + codec::Codec + Default + Copy @@ -56,67 +47,28 @@ pub trait Balances: System { + From<::BlockNumber>; } -/// The Balances extension trait for the Client. -pub trait BalancesStore { - /// Balances type. - type Balances: Balances; - - /// The 'free' balance of a given account. +/// All balance information for an account. +#[derive(Debug, Encode, Decode, Clone, PartialEq, Eq, Default)] +pub struct AccountData { + /// Non-reserved part of the balance. There may still be restrictions on this, but it is the + /// total pool what may in principle be transferred, reserved and used for tipping. /// - /// This is the only balance that matters in terms of most operations on - /// tokens. It alone is used to determine the balance when in the contract - /// execution environment. When this balance falls below the value of - /// `ExistentialDeposit`, then the 'current account' is deleted: - /// specifically `FreeBalance`. Further, the `OnFreeBalanceZero` callback - /// is invoked, giving a chance to external modules to clean up data - /// associated with the deleted account. + /// This is the only balance that matters in terms of most operations on tokens. It + /// alone is used to determine the balance when in the contract execution environment. + pub free: Balance, + /// Balance which is reserved and may not be used at all. /// - /// `system::AccountNonce` is also deleted if `ReservedBalance` is also - /// zero. It also gets collapsed to zero if it ever becomes less than - /// `ExistentialDeposit`. - fn free_balance( - &self, - account_id: ::AccountId, - ) -> Pin< - Box< - dyn Future::Balance, Error>> - + Send, - >, - >; -} - -impl BalancesStore for Client { - type Balances = T; - - fn free_balance( - &self, - account_id: ::AccountId, - ) -> Pin< - Box< - dyn Future::Balance, Error>> - + Send, - >, - > { - let free_balance_map = || { - Ok(self - .metadata() - .module("Balances")? - .storage("FreeBalance")? - .get_map::< - ::AccountId, - ::Balance>()?) - }; - let map = match free_balance_map() { - Ok(map) => map, - Err(err) => return Box::pin(future::err(err)), - }; - let client = self.clone(); - Box::pin(async move { - client - .fetch_or(map.key(account_id), None, map.default()) - .await - }) - } + /// This can still get slashed, but gets slashed last of all. + /// + /// This balance is a 'reserve' balance that other subsystems use in order to set aside tokens + /// that are still 'owned' by the account holder, but which are suspendable. + pub reserved: Balance, + /// The amount that `free` may not drop below when withdrawing for *anything except transaction + /// fee payment*. + pub misc_frozen: Balance, + /// The amount that `free` may not drop below when withdrawing specifically for transaction + /// fee payment. + pub fee_frozen: Balance, } const MODULE: &str = "Balances"; diff --git a/src/frame/contracts.rs b/src/frame/contracts.rs index 99c3cd62bd..52d702b146 100644 --- a/src/frame/contracts.rs +++ b/src/frame/contracts.rs @@ -212,12 +212,12 @@ mod tests { fn tx_instantiate() { env_logger::try_init().ok(); let result: Result<_, Error> = async_std::task::block_on(async move { - let signer = AccountKeyring::Alice.pair(); + let signer = AccountKeyring::Bob.pair(); let client = test_client().await; let code_hash = put_code(&client, signer.clone()).await?; - println!("{:?}", code_hash); + log::info!("Code hash: {:?}", code_hash); let xt = client.xt(signer, None).await?; let result = xt @@ -235,9 +235,11 @@ mod tests { Ok(event) }); + log::info!("Instantiate result: {:?}", result); + assert!( result.is_ok(), - "Contracts CodeStored event should be received and decoded" + "Contract should be instantiated successfully" ); } } diff --git a/src/frame/system.rs b/src/frame/system.rs index 7df1db866f..c1805b62b1 100644 --- a/src/frame/system.rs +++ b/src/frame/system.rs @@ -30,10 +30,11 @@ use sp_runtime::traits::{ Hash, Header, MaybeDisplay, + MaybeMallocSizeOf, MaybeSerialize, MaybeSerializeDeserialize, Member, - SimpleArithmetic, + AtLeast32Bit, SimpleBitOps, }; use std::{ @@ -60,16 +61,17 @@ pub trait System: 'static + Eq + Clone + Debug { + Debug + Default + MaybeDisplay - + SimpleArithmetic + + AtLeast32Bit + Copy; /// The block number type used by the runtime. type BlockNumber: Parameter + Member + + MaybeMallocSizeOf + MaybeSerializeDeserialize + Debug + MaybeDisplay - + SimpleArithmetic + + AtLeast32Bit + Default + Bounded + Copy @@ -79,6 +81,7 @@ pub trait System: 'static + Eq + Clone + Debug { /// The output of the `Hashing` function. type Hash: Parameter + Member + + MaybeMallocSizeOf + MaybeSerializeDeserialize + Debug + MaybeDisplay @@ -113,6 +116,10 @@ pub trait System: 'static + Eq + Clone + Debug { /// Extrinsic type within blocks. type Extrinsic: Parameter + Member + Extrinsic + Debug + MaybeSerializeDeserialize; + + /// Data to be associated with an account (other than nonce/transaction counter, which this + /// module does regardless). + type AccountData: Member + Codec + Clone + Default; } /// The System extension trait for the Client. @@ -120,12 +127,12 @@ pub trait SystemStore { /// System type. type System: System; - /// Returns the account nonce for an account_id. - fn account_nonce( + /// Returns the nonce and account data for an account_id. + fn account( &self, account_id: ::AccountId, ) -> Pin< - Box::Index, Error>> + Send>, + Box::Index, ::AccountData), Error>> + Send>, >; } @@ -134,20 +141,20 @@ impl SystemStore { type System = T; - fn account_nonce( + fn account( &self, account_id: ::AccountId, ) -> Pin< - Box::Index, Error>> + Send>, + Box::Index, ::AccountData), Error>> + Send>, > { - let account_nonce_map = || { + let account_map = || { Ok(self .metadata .module("System")? - .storage("AccountNonce")? + .storage("Account")? .get_map()?) }; - let map = match account_nonce_map() { + let map = match account_map() { Ok(map) => map, Err(err) => return Box::pin(future::err(err)), }; @@ -175,11 +182,17 @@ use frame_support::weights::DispatchInfo; /// Event for the System module. #[derive(Clone, Debug, codec::Decode)] -pub enum SystemEvent { +pub enum SystemEvent { /// An extrinsic completed successfully. ExtrinsicSuccess(DispatchInfo), /// An extrinsic failed. ExtrinsicFailed(sp_runtime::DispatchError, DispatchInfo), + /// `:code` was updated. + CodeUpdated, + /// A new account was created. + NewAccount(T::AccountId), + /// An account was reaped. + ReapedAccount(T::AccountId), } /// A phase of a block's execution. diff --git a/src/lib.rs b/src/lib.rs index e0acd6de08..850003fa0f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -311,7 +311,7 @@ impl Client { let account_id = S::Signer::from(signer.public()).into_account(); let nonce = match nonce { Some(nonce) => nonce, - None => self.account_nonce(account_id).await?, + None => self.account(account_id).await?.0, }; let genesis_hash = self.genesis_hash; @@ -491,15 +491,11 @@ mod tests { use super::*; use crate::{ - frame::balances::{ - Balances, - BalancesStore, - }, + frame::balances::Balances, DefaultNodeRuntime as Runtime, Error, }; - type Index = ::Index; type AccountId = ::AccountId; type Address = ::Address; type Balance = ::Balance; @@ -565,7 +561,7 @@ mod tests { let result: Result<_, Error> = async_std::task::block_on(async move { let account = AccountKeyring::Alice.to_account_id(); let client = test_client().await; - let balance = client.free_balance(account.into()).await?; + let balance = client.account(account.into()).await?.1.free; Ok(balance) }); @@ -614,32 +610,18 @@ mod tests { let call2 = balances.call("transfer", subxt_transfer.args).unwrap(); assert_eq!(call.encode().to_vec(), call2.0); - let free_balance = - >::hashed_key_for(&dest); - let free_balance_key = StorageKey(free_balance); - let free_balance_key2 = client - .metadata() - .module("Balances") - .unwrap() - .storage("FreeBalance") - .unwrap() - .get_map::() - .unwrap() - .key(dest.clone()); - assert_eq!(free_balance_key, free_balance_key2); - - let account_nonce = - >::hashed_key_for(&dest); - let account_nonce_key = StorageKey(account_nonce); - let account_nonce_key2 = client + let account_key = + >::hashed_key_for(&dest); + let account_key_substrate = StorageKey(account_key); + let account_key_from_meta = client .metadata() .module("System") .unwrap() - .storage("AccountNonce") + .storage("Account") .unwrap() - .get_map::() + .get_map::>() .unwrap() - .key(dest); - assert_eq!(account_nonce_key, account_nonce_key2); + .key(dest.clone()); + assert_eq!(account_key_substrate, account_key_from_meta); } } diff --git a/src/rpc.rs b/src/rpc.rs index 7454dc6b82..cd15587e67 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -340,9 +340,13 @@ impl Rpc { } } } + TransactionStatus::Invalid => return Err("Extrinsic Invalid".into()), TransactionStatus::Usurped(_) => return Err("Extrinsic Usurped".into()), TransactionStatus::Dropped => return Err("Extrinsic Dropped".into()), - TransactionStatus::Invalid => return Err("Extrinsic Invalid".into()), + TransactionStatus::Retracted(_) => return Err("Extrinsic Retracted".into()), + // should have made it `InBlock` before either of these + TransactionStatus::Finalized(_) => return Err("Extrinsic Finalized".into()), + TransactionStatus::FinalityTimeout(_) => return Err("Extrinsic FinalityTimeout".into()), } } unreachable!() @@ -357,7 +361,7 @@ pub struct ExtrinsicSuccess { /// Extrinsic hash. pub extrinsic: T::Hash, /// Raw runtime events, can be decoded by the caller. - pub events: Vec, + pub events: Vec>, } impl ExtrinsicSuccess { @@ -377,7 +381,7 @@ impl ExtrinsicSuccess { } /// Returns all System Events - pub fn system_events(&self) -> Vec<&SystemEvent> { + pub fn system_events(&self) -> Vec<&SystemEvent> { self.events .iter() .filter_map(|evt| { diff --git a/src/runtimes.rs b/src/runtimes.rs index 7815b418d9..0d4cc45276 100644 --- a/src/runtimes.rs +++ b/src/runtimes.rs @@ -26,7 +26,7 @@ use sp_runtime::{ }; use crate::frame::{ - balances::Balances, + balances::{Balances, AccountData}, contracts::Contracts, system::System, }; @@ -49,6 +49,7 @@ impl System for DefaultNodeRuntime { type Address = pallet_indices::address::Address; type Header = Header; type Extrinsic = OpaqueExtrinsic; + type AccountData = AccountData<::Balance>; } impl Balances for DefaultNodeRuntime {