Double map and plain storage support, introduce macros (#93)

* Support custom clients.

* Simplify trait bounds.

* Plain and double map storage support.

* Simplify more trait bounds.

* Add proc macro.

* Add Call, Event and Store traits.

* Update proc-macros.

* Add with_system for proc-macro.

* proc-macro: test: support signature and extra fields.

* proc-macro: test: support sharing state accross steps.

* proc-macro: test: fetch state sequentially.

* Elide lifetimes.

* Add test for plain storage.

* Run rustfmt.
This commit is contained in:
David Craven
2020-04-28 21:04:26 +02:00
committed by GitHub
parent 216b5614dd
commit 6f27489378
20 changed files with 1924 additions and 501 deletions
+27 -59
View File
@@ -22,11 +22,8 @@ use codec::{
Encode,
};
use frame_support::Parameter;
use futures::future::{
self,
Future,
};
use serde::de::DeserializeOwned;
use sp_core::storage::StorageKey;
use sp_runtime::{
traits::{
AtLeast32Bit,
@@ -40,24 +37,21 @@ use sp_runtime::{
MaybeSerialize,
MaybeSerializeDeserialize,
Member,
SignedExtension,
SimpleBitOps,
},
RuntimeDebug,
};
use std::{
fmt::Debug,
pin::Pin,
};
use std::fmt::Debug;
use crate::{
error::Error,
extrinsic::SignedExtra,
frame::{
balances::Balances,
Call,
Store,
},
metadata::{
Metadata,
MetadataError,
},
Client,
};
/// The subset of the `frame::Trait` that a client must implement.
@@ -116,7 +110,7 @@ pub trait System: 'static + Eq + Clone + Debug {
+ Default;
/// The address type. This instead of `<frame_system::Trait::Lookup as StaticLookup>::Source`.
type Address: Codec + Clone + PartialEq + Debug;
type Address: Codec + Clone + PartialEq + Debug + Send + Sync;
/// The block header.
type Header: Parameter
@@ -147,59 +141,33 @@ pub struct AccountInfo<T: System> {
pub data: T::AccountData,
}
/// The System extension trait for the Client.
pub trait SystemStore {
/// System type.
type System: System;
const MODULE: &str = "System";
/// Returns the nonce and account data for an account_id.
fn account(
&self,
account_id: <Self::System as System>::AccountId,
) -> Pin<Box<dyn Future<Output = Result<AccountInfo<Self::System>, Error>> + Send>>;
}
/// Account field of the `System` module.
#[derive(Encode)]
pub struct AccountStore<'a, T: System>(pub &'a T::AccountId);
impl<T: System + Balances + Sync + Send + 'static, S: 'static, E> SystemStore
for Client<T, S, E>
where
E: SignedExtra<T> + SignedExtension + 'static,
{
type System = T;
impl<'a, T: System> Store<T> for AccountStore<'a, T> {
const MODULE: &'static str = MODULE;
const FIELD: &'static str = "Account";
type Returns = AccountInfo<T>;
fn account(
&self,
account_id: <Self::System as System>::AccountId,
) -> Pin<Box<dyn Future<Output = Result<AccountInfo<Self::System>, Error>> + Send>>
{
let account_map = || {
Ok(self
.metadata
.module("System")?
.storage("Account")?
.get_map()?)
};
let map = match account_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
})
fn key(&self, metadata: &Metadata) -> Result<StorageKey, MetadataError> {
Ok(metadata
.module(Self::MODULE)?
.storage(Self::FIELD)?
.map()?
.key(self.0))
}
}
const MODULE: &str = "System";
const SET_CODE: &str = "set_code";
/// Arguments for updating the runtime code
pub type SetCode = Vec<u8>;
#[derive(Encode)]
pub struct SetCodeCall<'a>(pub &'a Vec<u8>);
/// Sets the new code.
pub fn set_code(code: Vec<u8>) -> Call<SetCode> {
Call::new(MODULE, SET_CODE, code)
impl<'a, T: System> Call<T> for SetCodeCall<'a> {
const MODULE: &'static str = MODULE;
const FUNCTION: &'static str = "set_code";
}
use frame_support::weights::DispatchInfo;