From 4769b4b0166d7f5d6f81390a5a453625a20f845c Mon Sep 17 00:00:00 2001 From: Qinxuan Chen Date: Tue, 26 Nov 2019 20:09:17 +0800 Subject: [PATCH] Use thiserror instead of derive_more (#44) - Use thiserror instead of derive_more - Format code - Fix clippy warnings - Add LICENSE_TEMPLATE Signed-off-by: koushiro --- Cargo.toml | 23 +++++------ LICENSE_TEMPLATE | 15 +++++++ src/codec.rs | 16 +++++++ src/error.rs | 59 +++++++++++++++++++------- src/events.rs | 61 ++++++++++++++++----------- src/extrinsic.rs | 29 +++++++------ src/frame/balances.rs | 45 +++++++++++++++----- src/frame/contracts.rs | 52 +++++++++++++++++++---- src/frame/mod.rs | 26 +++++++++++- src/frame/system.rs | 40 +++++++++++++----- src/lib.rs | 94 +++++++++++++++++++++--------------------- src/metadata.rs | 59 ++++++++++++++++++-------- src/rpc.rs | 89 +++++++++++++++++++++------------------ src/runtimes.rs | 11 ++--- 14 files changed, 414 insertions(+), 205 deletions(-) create mode 100644 LICENSE_TEMPLATE diff --git a/Cargo.toml b/Cargo.toml index 39484b143c..4a88b7213b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,23 +6,23 @@ edition = "2018" license = "GPL-3.0" readme = "README.md" - description = "Submit extrinsics (transactions) to a substrate node via RPC" keywords = ["parity", "substrate", "blockchain"] - -include = ["/Cargo.toml", "src/**/*.rs", "/README.md", "/LICENSE"] +include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE"] [dependencies] -derive_more = "0.14.0" log = "0.4" -futures = "0.1.28" +thiserror = "1.0" +futures = "0.1" jsonrpc-core-client = { version = "14.0", features = ["ws"] } num-traits = { version = "0.2", default-features = false } -parity-scale-codec = { version = "1.0", default-features = false, features = ["derive", "full"] } +serde = { version = "1.0", features = ["derive"] } +url = "1.7" +parity-scale-codec = { version = "1.1", default-features = false, features = ["derive", "full"] } + runtime_metadata = { git = "https://github.com/paritytech/substrate/", package = "frame-metadata" } runtime_support = { git = "https://github.com/paritytech/substrate/", package = "frame-support" } runtime_primitives = { git = "https://github.com/paritytech/substrate/", package = "sr-primitives" } -serde = { version = "1.0", features = ["derive"] } sr-version = { git = "https://github.com/paritytech/substrate/", package = "sr-version" } frame-system = { git = "https://github.com/paritytech/substrate/", package = "frame-system" } pallet-balances = { git = "https://github.com/paritytech/substrate/", package = "pallet-balances" } @@ -31,12 +31,11 @@ pallet-indices = { git = "https://github.com/paritytech/substrate/", package = " substrate-rpc-api = { git = "https://github.com/paritytech/substrate/", package = "substrate-rpc-api" } substrate-rpc-primitives = { git = "https://github.com/paritytech/substrate/", package = "substrate-rpc-primitives" } substrate-primitives = { git = "https://github.com/paritytech/substrate/", package = "substrate-primitives" } -txpool = { git = "https://github.com/paritytech/substrate/", package = "substrate-transaction-graph" } -url = "1.7" +txpool = { git = "https://github.com/paritytech/substrate/", package = "substrate-transaction-graph" } [dev-dependencies] -env_logger = "0.6" +env_logger = "0.7" +tokio = "0.1" +wabt = "0.9" node-runtime = { git = "https://github.com/paritytech/substrate/", package = "node-runtime" } substrate-keyring = { git = "https://github.com/paritytech/substrate/", package = "substrate-keyring" } -tokio = "0.1" -wabt = "0.9.0" diff --git a/LICENSE_TEMPLATE b/LICENSE_TEMPLATE new file mode 100644 index 0000000000..03419d93b9 --- /dev/null +++ b/LICENSE_TEMPLATE @@ -0,0 +1,15 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of substrate-subxt. +// +// subxt is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// subxt is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with substrate-subxt. If not, see . diff --git a/src/codec.rs b/src/codec.rs index 4cebf2a777..9f9727bcec 100644 --- a/src/codec.rs +++ b/src/codec.rs @@ -1,3 +1,19 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of substrate-subxt. +// +// subxt is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// subxt is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with substrate-subxt. If not, see . + use parity_scale_codec::Encode; #[derive(Clone)] diff --git a/src/error.rs b/src/error.rs index 9e9cfb98cb..52d995f85a 100644 --- a/src/error.rs +++ b/src/error.rs @@ -14,41 +14,70 @@ // You should have received a copy of the GNU General Public License // along with substrate-subxt. If not, see . +use jsonrpc_core_client::RpcError; +use runtime_primitives::transaction_validity::TransactionValidityError; +use substrate_primitives::crypto::SecretStringError; + use crate::{ events::EventsError, metadata::MetadataError, }; -use jsonrpc_core_client::RpcError; -use parity_scale_codec::Error as CodecError; -use runtime_primitives::transaction_validity::TransactionValidityError; -use std::io::Error as IoError; -use substrate_primitives::crypto::SecretStringError; /// Error enum. -#[derive(Debug, derive_more::From, derive_more::Display)] +#[derive(Debug, thiserror::Error)] pub enum Error { - /// Codec error. - Codec(CodecError), - /// Events error. - Events(EventsError), /// Io error. - Io(IoError), + #[error("Io error: {0}")] + Io(#[from] std::io::Error), + /// Codec error. + #[error("Scale codec error: {0}")] + Codec(#[from] parity_scale_codec::Error), /// Rpc error. + #[error("Rpc error: {0}")] Rpc(RpcError), /// Secret string error. - #[display(fmt = "Secret String Error")] + #[error("Secret String Error")] SecretString(SecretStringError), - /// Metadata error. - Metadata(MetadataError), /// Extrinsic validity error - #[display(fmt = "Transaction Validity Error: {:?}", _0)] + #[error("Transaction Validity Error: {0:?}")] Invalid(TransactionValidityError), + /// Events error. + #[error("Event error: {0}")] + Events(#[from] EventsError), + /// Metadata error. + #[error("Metadata error: {0}")] + Metadata(#[from] MetadataError), /// Other error. + #[error("Other error: {0}")] Other(String), } +impl From for Error { + fn from(error: RpcError) -> Self { + Error::Rpc(error) + } +} + +impl From for Error { + fn from(error: SecretStringError) -> Self { + Error::SecretString(error) + } +} + +impl From for Error { + fn from(error: TransactionValidityError) -> Self { + Error::Invalid(error) + } +} + impl From<&str> for Error { fn from(error: &str) -> Self { Error::Other(error.into()) } } + +impl From for Error { + fn from(error: String) -> Self { + Error::Other(error) + } +} diff --git a/src/events.rs b/src/events.rs index 1d4011f071..10be5a6b55 100644 --- a/src/events.rs +++ b/src/events.rs @@ -14,27 +14,6 @@ // You should have received a copy of the GNU General Public License // along with substrate-subxt. If not, see . -use crate::{ - metadata::{ - EventArg, - Metadata, - MetadataError, - }, - frame::balances::Balances, - System, - SystemEvent, -}; -use log; -use frame_system::Phase; -use parity_scale_codec::{ - Codec, - Compact, - Decode, - Encode, - Error as CodecError, - Input, - Output, -}; use std::{ collections::{ HashMap, @@ -47,6 +26,29 @@ use std::{ }, }; +use parity_scale_codec::{ + Codec, + Compact, + Decode, + Encode, + Error as CodecError, + Input, + Output, +}; + +use frame_system::Phase; + +use crate::{ + frame::balances::Balances, + metadata::{ + EventArg, + Metadata, + MetadataError, + }, + System, + SystemEvent, +}; + /// Top level Event that can be produced by a substrate runtime #[derive(Debug)] pub enum RuntimeEvent { @@ -65,15 +67,24 @@ pub struct RawEvent { pub data: Vec, } -#[derive(Debug, derive_more::From, derive_more::Display)] +#[derive(Debug, thiserror::Error)] pub enum EventsError { - CodecError(CodecError), - Metadata(MetadataError), - #[display(fmt = "Type Sizes Missing: {:?}", _0)] + #[error("Scale codec error: {0:?}")] + CodecError(#[from] CodecError), + #[error("Metadata error: {0:?}")] + Metadata(#[from] MetadataError), + #[error("Type Sizes Missing: {0:?}")] TypeSizesMissing(Vec), + #[error("Type Sizes Unavailable: {0:?}")] TypeSizeUnavailable(String), } +impl From> for EventsError { + fn from(error: Vec) -> Self { + EventsError::TypeSizesMissing(error) + } +} + pub struct EventsDecoder { metadata: Metadata, // todo: [AJ] borrow? type_sizes: HashMap, diff --git a/src/extrinsic.rs b/src/extrinsic.rs index 0374273b43..c4cae79a13 100644 --- a/src/extrinsic.rs +++ b/src/extrinsic.rs @@ -14,15 +14,14 @@ // You should have received a copy of the GNU General Public License // along with substrate-subxt. If not, see . -use crate::frame::{ - balances::Balances, - system::System, -}; +use std::marker::PhantomData; + use parity_scale_codec::{ Codec, Decode, Encode, }; + use runtime_primitives::{ generic::{ Era, @@ -36,9 +35,13 @@ use runtime_primitives::{ }, transaction_validity::TransactionValidityError, }; -use std::marker::PhantomData; use substrate_primitives::Pair; +use crate::frame::{ + balances::Balances, + system::System, +}; + /// SignedExtra checks copied from substrate, in order to remove requirement to implement /// substrate's `frame_system::Trait` @@ -63,8 +66,8 @@ where type AccountId = u64; type Call = (); type AdditionalSigned = u32; - type DispatchInfo = (); type Pre = (); + type DispatchInfo = (); fn additional_signed( &self, ) -> Result { @@ -93,8 +96,8 @@ where type AccountId = u64; type Call = (); type AdditionalSigned = T::Hash; - type DispatchInfo = (); type Pre = (); + type DispatchInfo = (); fn additional_signed( &self, ) -> Result { @@ -125,8 +128,8 @@ where type AccountId = u64; type Call = (); type AdditionalSigned = T::Hash; - type DispatchInfo = (); type Pre = (); + type DispatchInfo = (); fn additional_signed( &self, ) -> Result { @@ -145,8 +148,8 @@ where type AccountId = u64; type Call = (); type AdditionalSigned = (); - type DispatchInfo = (); type Pre = (); + type DispatchInfo = (); fn additional_signed( &self, ) -> Result { @@ -165,8 +168,8 @@ where type AccountId = u64; type Call = (); type AdditionalSigned = (); - type DispatchInfo = (); type Pre = (); + type DispatchInfo = (); fn additional_signed( &self, ) -> Result { @@ -186,8 +189,8 @@ where type AccountId = u64; type Call = (); type AdditionalSigned = (); - type DispatchInfo = (); type Pre = (); + type DispatchInfo = (); fn additional_signed( &self, ) -> Result { @@ -206,8 +209,8 @@ where type AccountId = u64; type Call = (); type AdditionalSigned = (); - type DispatchInfo = (); type Pre = (); + type DispatchInfo = (); fn additional_signed( &self, ) -> Result { @@ -267,8 +270,8 @@ impl SignedExtension for DefaultExtra { type Call = (); type AdditionalSigned = <>::Extra as SignedExtension>::AdditionalSigned; - type DispatchInfo = (); type Pre = (); + type DispatchInfo = (); fn additional_signed( &self, diff --git a/src/frame/balances.rs b/src/frame/balances.rs index 968dbbdb5f..defc3fe8f1 100644 --- a/src/frame/balances.rs +++ b/src/frame/balances.rs @@ -1,24 +1,47 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of substrate-subxt. +// +// subxt is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// subxt is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with substrate-subxt. If not, see . + //! Implements support for the pallet_balances module. -use crate::{ - error::Error, - frame::{ - Call, - system::System, - }, - Client, -}; + +use std::fmt::Debug; + use futures::future::{ self, Future, }; -use parity_scale_codec::{Encode, Codec}; +use parity_scale_codec::{ + Codec, + Encode, +}; + use runtime_primitives::traits::{ MaybeSerialize, Member, SimpleArithmetic, }; use runtime_support::Parameter; -use std::fmt::Debug; + +use crate::{ + error::Error, + frame::{ + system::System, + Call, + }, + Client, +}; /// The subset of the `pallet_balances::Trait` that a client must implement. pub trait Balances: System { @@ -99,7 +122,7 @@ const TRANSFER: &str = "transfer"; pub struct TransferArgs { to: ::Address, #[codec(compact)] - amount: ::Balance + amount: ::Balance, } /// Transfer some liquid free balance to another account. diff --git a/src/frame/contracts.rs b/src/frame/contracts.rs index d5da4cd7e1..613a74a4bd 100644 --- a/src/frame/contracts.rs +++ b/src/frame/contracts.rs @@ -1,13 +1,29 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of substrate-subxt. +// +// subxt is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// subxt is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with substrate-subxt. If not, see . + //! Implements support for the pallet_contracts module. -use crate::{ - frame::{ - Call, - balances::Balances, - system::System, - }, -}; + use parity_scale_codec::Encode; +use crate::frame::{ + balances::Balances, + system::System, + Call, +}; + const MODULE: &str = "Contracts"; const PUT_CODE: &str = "put_code"; const CREATE: &str = "create"; @@ -74,7 +90,16 @@ pub fn create( code_hash: ::Hash, data: Vec, ) -> Call> { - Call::new(MODULE, CREATE, CreateArgs { endowment, gas_limit, code_hash, data }) + Call::new( + MODULE, + CREATE, + CreateArgs { + endowment, + gas_limit, + code_hash, + data, + }, + ) } /// Makes a call to an account, optionally transferring some balance. @@ -91,5 +116,14 @@ pub fn call( gas_limit: Gas, data: Vec, ) -> Call> { - Call::new(MODULE, CALL, CallArgs { dest, value, gas_limit, data }) + Call::new( + MODULE, + CALL, + CallArgs { + dest, + value, + gas_limit, + data, + }, + ) } diff --git a/src/frame/mod.rs b/src/frame/mod.rs index 160ecdcf75..d5fc55a336 100644 --- a/src/frame/mod.rs +++ b/src/frame/mod.rs @@ -1,3 +1,19 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of substrate-subxt. +// +// subxt is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// subxt is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with substrate-subxt. If not, see . + //! Implements support for built-in runtime modules. use parity_scale_codec::Encode; @@ -8,13 +24,21 @@ pub mod system; /// Creates module calls pub struct Call { + /// Module name pub module: &'static str, + /// Function name pub function: &'static str, + /// Call arguments pub args: T, } impl Call { + /// Create a module call pub fn new(module: &'static str, function: &'static str, args: T) -> Self { - Call { module, function, args } + Call { + module, + function, + args, + } } } diff --git a/src/frame/system.rs b/src/frame/system.rs index 6d985d98ca..6d1c51d3e9 100644 --- a/src/frame/system.rs +++ b/src/frame/system.rs @@ -1,17 +1,30 @@ +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of substrate-subxt. +// +// subxt is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// subxt is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with substrate-subxt. If not, see . + //! Implements support for the frame_system module. -use crate::{ - error::Error, - frame::{ - Call, - balances::Balances, - }, - Client, -}; + +use std::fmt::Debug; + use futures::future::{ self, Future, }; use parity_scale_codec::Codec; +use serde::de::DeserializeOwned; + use runtime_primitives::traits::{ Bounded, CheckEqual, @@ -26,8 +39,15 @@ use runtime_primitives::traits::{ StaticLookup, }; use runtime_support::Parameter; -use serde::de::DeserializeOwned; -use std::fmt::Debug; + +use crate::{ + error::Error, + frame::{ + balances::Balances, + Call, + }, + Client, +}; /// The subset of the `frame::Trait` that a client must implement. pub trait System: 'static + Eq + Clone + Debug { diff --git a/src/lib.rs b/src/lib.rs index b8eba40e67..1417d5a1f2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -19,6 +19,12 @@ #![deny(missing_docs)] #![deny(warnings)] +#![allow(clippy::type_complexity)] + +use std::{ + convert::TryFrom, + marker::PhantomData, +}; use futures::future::{ self, @@ -27,7 +33,6 @@ use futures::future::{ IntoFuture, }; use jsonrpc_core_client::transports::ws; -use metadata::Metadata; use parity_scale_codec::{ Codec, Decode, @@ -42,10 +47,6 @@ use runtime_primitives::{ MultiSignature, }; use sr_version::RuntimeVersion; -use std::{ - convert::TryFrom, - marker::PhantomData, -}; use substrate_primitives::{ storage::{ StorageChangeSet, @@ -55,7 +56,16 @@ use substrate_primitives::{ }; use url::Url; -use crate::{ +mod codec; +mod error; +mod events; +mod extrinsic; +mod frame; +mod metadata; +mod rpc; +mod runtimes; + +use self::{ codec::Encoded, events::EventsDecoder, extrinsic::{ @@ -63,7 +73,6 @@ use crate::{ SignedExtra, }, frame::{ - Call, balances::Balances, system::{ System, @@ -71,6 +80,7 @@ use crate::{ SystemStore, }, }, + metadata::Metadata, rpc::{ BlockNumber, ChainBlock, @@ -78,27 +88,20 @@ use crate::{ Rpc, }, }; - -mod codec; -mod error; -mod events; -mod extrinsic; -mod metadata; -mod frame; -mod rpc; -mod runtimes; - -pub use error::Error; -pub use events::RawEvent; -pub use frame::*; -pub use rpc::ExtrinsicSuccess; -pub use runtimes::*; +pub use self::{ + error::Error, + events::RawEvent, + frame::*, + rpc::ExtrinsicSuccess, + runtimes::*, +}; fn connect(url: &Url) -> impl Future, Error = Error> { ws::connect(url).map_err(Into::into) } /// ClientBuilder for constructing a Client. +#[derive(Default)] pub struct ClientBuilder { _marker: std::marker::PhantomData<(T, S)>, url: Option, @@ -153,7 +156,7 @@ impl Clone for Client { fn clone(&self) -> Self { Self { url: self.url.clone(), - genesis_hash: self.genesis_hash.clone(), + genesis_hash: self.genesis_hash, metadata: self.metadata.clone(), runtime_version: self.runtime_version.clone(), _marker: PhantomData, @@ -258,7 +261,7 @@ impl Client { None => Either::B(self.account_nonce(account_id)), } .map(|nonce| { - let genesis_hash = client.genesis_hash.clone(); + let genesis_hash = client.genesis_hash; let runtime_version = client.runtime_version.clone(); XtBuilder { client, @@ -291,7 +294,7 @@ where /// Returns the nonce. pub fn nonce(&self) -> T::Index { - self.nonce.clone() + self.nonce } /// Sets the nonce to a new value. @@ -331,9 +334,9 @@ where C: parity_scale_codec::Encode, { let signer = self.signer.clone(); - let account_nonce = self.nonce.clone(); + let account_nonce = self.nonce; let version = self.runtime_version.spec_version; - let genesis_hash = self.genesis_hash.clone(); + let genesis_hash = self.genesis_hash; let call = self .metadata() .module(&call.module) @@ -351,7 +354,10 @@ where } /// Submits a transaction to the chain. - pub fn submit(&self, call: Call) -> impl Future { + pub fn submit( + &self, + call: Call, + ) -> impl Future { let cli = self.client.connect(); self.create_and_sign(call) .into_future() @@ -364,7 +370,7 @@ where /// Submits transaction to the chain and watch for events. pub fn submit_and_watch( &self, - call: Call + call: Call, ) -> impl Future, Error = Error> { let cli = self.client.connect(); let metadata = self.client.metadata().clone(); @@ -386,22 +392,21 @@ where #[cfg(test)] mod tests { - use super::*; - use crate::{ - frame::{ - balances::{ - Balances, - BalancesStore, - }, - }, - DefaultNodeRuntime as Runtime, - }; use futures::stream::Stream; use parity_scale_codec::Encode; use runtime_support::StorageMap; use substrate_keyring::AccountKeyring; use substrate_primitives::storage::StorageKey; + use super::*; + use crate::{ + frame::balances::{ + Balances, + BalancesStore, + }, + DefaultNodeRuntime as Runtime, + }; + type Index = ::Index; type AccountId = ::AccountId; type Address = ::Address; @@ -424,8 +429,8 @@ mod tests { let mut xt = rt.block_on(client.xt(signer, None)).unwrap(); let dest = AccountKeyring::Bob.to_account_id(); - let transfer = xt - .submit(balances::transfer::(dest.clone().into(), 10_000)); + let transfer = + xt.submit(balances::transfer::(dest.clone().into(), 10_000)); rt.block_on(transfer).unwrap(); // check that nonce is handled correctly @@ -452,8 +457,7 @@ mod tests { "#; let wasm = wabt::wat2wasm(CONTRACT).expect("invalid wabt"); - let put_code = xt - .submit_and_watch(contracts::put_code(500_000, wasm)); + let put_code = xt.submit_and_watch(contracts::put_code(500_000, wasm)); let success = rt .block_on(put_code) @@ -531,9 +535,7 @@ mod tests { let transfer = pallet_balances::Call::transfer(address.clone(), amount); let call = node_runtime::Call::Balances(transfer); let subxt_transfer = crate::frame::balances::transfer::(address, amount); - let call2 = balances - .call("transfer", subxt_transfer.args) - .unwrap(); + let call2 = balances.call("transfer", subxt_transfer.args).unwrap(); assert_eq!(call.encode().to_vec(), call2.0); let free_balance = diff --git a/src/metadata.rs b/src/metadata.rs index 8f8e46fe92..61e6e2a63a 100644 --- a/src/metadata.rs +++ b/src/metadata.rs @@ -1,8 +1,31 @@ -use crate::codec::Encoded; +// Copyright 2019 Parity Technologies (UK) Ltd. +// This file is part of substrate-subxt. +// +// subxt is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// subxt is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with substrate-subxt. If not, see . + +use std::{ + collections::HashMap, + convert::TryFrom, + marker::PhantomData, + str::FromStr, +}; + use parity_scale_codec::{ Decode, Encode, }; + use runtime_metadata::{ DecodeDifferent, RuntimeMetadata, @@ -12,21 +35,23 @@ use runtime_metadata::{ StorageHasher, META_RESERVED, }; -use std::{ - collections::HashMap, - convert::TryFrom, - marker::PhantomData, - str::FromStr, -}; use substrate_primitives::storage::StorageKey; -#[derive(Debug, Clone, derive_more::Display)] +use crate::codec::Encoded; + +#[derive(Debug, thiserror::Error)] pub enum MetadataError { + #[error("Module not found")] ModuleNotFound(String), + #[error("Call not found")] CallNotFound(&'static str), + #[error("Event not found")] EventNotFound(u8), + #[error("Storage not found")] StorageNotFound(&'static str), + #[error("Storage type error")] StorageTypeError, + #[error("Map value type error")] MapValueTypeError, } @@ -63,17 +88,17 @@ impl Metadata { for (name, module) in &self.modules { string.push_str(name.as_str()); string.push('\n'); - for (storage, _) in &module.storage { + for storage in module.storage.keys() { string.push_str(" s "); string.push_str(storage.as_str()); string.push('\n'); } - for (call, _) in &module.calls { + for call in module.calls.keys() { string.push_str(" c "); string.push_str(call.as_str()); string.push('\n'); } - for (_, event) in &module.events { + for event in module.events.values() { string.push_str(" e "); string.push_str(event.name.as_str()); string.push('\n'); @@ -199,7 +224,7 @@ pub struct ModuleEventMetadata { impl ModuleEventMetadata { pub fn arguments(&self) -> Vec { - self.arguments.iter().cloned().collect() + self.arguments.to_vec() } } @@ -228,8 +253,8 @@ impl FromStr for EventArg { "Expected closing `>` for `Vec`", )) } - } else if s.starts_with("(") { - if s.ends_with(")") { + } else if s.starts_with('(') { + if s.ends_with(')') { let mut args = Vec::new(); for arg in s[1..s.len() - 1].split(',') { let arg = arg.trim().parse()?; @@ -278,11 +303,11 @@ impl TryFrom for Metadata { fn try_from(metadata: RuntimeMetadataPrefixed) -> Result { if metadata.0 != META_RESERVED { - Err(Error::InvalidPrefix)?; + return Err(Error::InvalidPrefix) } let meta = match metadata.1 { RuntimeMetadata::V8(meta) => meta, - _ => Err(Error::InvalidVersion)?, + _ => return Err(Error::InvalidVersion), }; let mut modules = HashMap::new(); let mut modules_by_event_index = HashMap::new(); @@ -293,7 +318,7 @@ impl TryFrom for Metadata { // modules with no events have no corresponding definition in the top level enum if !module_metadata.events.is_empty() { modules_by_event_index.insert(event_index, module_name.clone()); - event_index = event_index + 1; + event_index += 1; } modules.insert(module_name, module_metadata); } diff --git a/src/rpc.rs b/src/rpc.rs index cc7062b437..9b0ec92e96 100644 --- a/src/rpc.rs +++ b/src/rpc.rs @@ -14,24 +14,23 @@ // You should have received a copy of the GNU General Public License // along with substrate-subxt. If not, see . -use crate::{ - error::Error, - events::{ - EventsDecoder, - RuntimeEvent, +use std::convert::TryInto; + +use futures::{ + future::{ + self, + Future, + IntoFuture, }, - metadata::Metadata, - frame::{ - balances::Balances, - system::System, + stream::{ + self, + Stream, }, }; -use futures::future::{ - self, - Future, +use jsonrpc_core_client::{ + RpcChannel, + TypedSubscriptionStream, }; -use jsonrpc_core_client::RpcChannel; -use log; use num_traits::bounds::Bounded; use parity_scale_codec::{ Decode, @@ -39,23 +38,48 @@ use parity_scale_codec::{ Error as CodecError, }; +use frame_system::Phase; use runtime_metadata::RuntimeMetadataPrefixed; use runtime_primitives::{ generic::{ Block, SignedBlock, }, + traits::Hash, OpaqueExtrinsic, }; use sr_version::RuntimeVersion; -use std::convert::TryInto; -use substrate_primitives::storage::StorageKey; +use substrate_primitives::{ + storage::{ + StorageChangeSet, + StorageKey, + }, + twox_128, +}; use substrate_rpc_api::{ author::AuthorClient, chain::ChainClient, state::StateClient, }; use substrate_rpc_primitives::number::NumberOrHex; +use txpool::watcher::Status; + +use crate::{ + error::Error, + events::{ + EventsDecoder, + RawEvent, + RuntimeEvent, + }, + frame::{ + balances::Balances, + system::{ + System, + SystemEvent, + }, + }, + metadata::Metadata, +}; pub type ChainBlock = SignedBlock::Header, OpaqueExtrinsic>>; pub type BlockNumber = NumberOrHex<::BlockNumber>; @@ -105,7 +129,9 @@ impl Rpc { .block_hash(Some(NumberOrHex::Number(block_zero))) .map_err(Into::into) .and_then(|genesis_hash| { - future::result(genesis_hash.ok_or("Genesis hash not found".into())) + future::result( + genesis_hash.ok_or_else(|| "Genesis hash not found".into()), + ) }) } @@ -144,26 +170,6 @@ impl Rpc { self.state.runtime_version(at).map_err(Into::into) } } -use futures::{ - future::IntoFuture, - stream::{ - self, - Stream, - }, -}; -use jsonrpc_core_client::TypedSubscriptionStream; -use runtime_primitives::traits::Hash; -use substrate_primitives::{ - storage::StorageChangeSet, - twox_128, -}; -use txpool::watcher::Status; - -use crate::{ - events::RawEvent, - frame::system::SystemEvent, -}; -use frame_system::Phase; type MapClosure = Box T + Send>; pub type MapStream = stream::Map, MapClosure>; @@ -271,7 +277,7 @@ impl Rpc { log::info!("received result {:?}", result); result - .ok_or(Error::from("Stream terminated")) + .ok_or_else(|| Error::from("Stream terminated")) .and_then(|r| r) .into_future() }) @@ -284,7 +290,7 @@ impl Rpc { .map_err(Into::into) }) .and_then(|(h, b)| { - b.ok_or(format!("Failed to find block {:?}", h).into()) + b.ok_or_else(|| format!("Failed to find block {:?}", h).into()) .map(|b| (h, b)) .into_future() }) @@ -370,10 +376,11 @@ pub fn wait_for_block_events( let hash = T::Hashing::hash_of(ext); hash == ext_hash }) - .ok_or(format!("Failed to find Extrinsic with hash {:?}", ext_hash).into()) + .ok_or_else(|| { + format!("Failed to find Extrinsic with hash {:?}", ext_hash).into() + }) .into_future(); - let block_hash = block_hash.clone(); events_stream .filter(move |event| event.block == block_hash) .into_future() diff --git a/src/runtimes.rs b/src/runtimes.rs index e471f39d4b..ebaf0b8bad 100644 --- a/src/runtimes.rs +++ b/src/runtimes.rs @@ -14,11 +14,6 @@ // You should have received a copy of the GNU General Public License // along with substrate-subxt. If not, see . -use crate::frame::{ - balances::Balances, - contracts::Contracts, - system::System, -}; use runtime_primitives::{ generic::Header, traits::{ @@ -29,6 +24,12 @@ use runtime_primitives::{ MultiSignature, }; +use crate::frame::{ + balances::Balances, + contracts::Contracts, + system::System, +}; + /// Concrete type definitions compatible with those in the default substrate `node_runtime` /// /// # Note