mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-15 22:01:04 +00:00
Misc changes (#2)
* Remove dependency on tokio, submit returns a future * Enable logging in tests * Add fetch, fetch_or, fetch_or_default
This commit is contained in:
committed by
Andrew Jones
parent
5a046d043e
commit
6522bb08d0
+2
-2
@@ -14,7 +14,6 @@ include = ["/Cargo.toml", "src/**/*.rs", "/README.md", "/LICENSE"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
derive_more = "0.14.0"
|
derive_more = "0.14.0"
|
||||||
env_logger = "0.6"
|
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
futures = "0.1.28"
|
futures = "0.1.28"
|
||||||
jsonrpc-core-client = { version = "12.1.0", features = ["ws"] }
|
jsonrpc-core-client = { version = "12.1.0", features = ["ws"] }
|
||||||
@@ -27,10 +26,11 @@ srml-system = { git = "https://github.com/paritytech/substrate/", package = "srm
|
|||||||
substrate-rpc = { git = "https://github.com/paritytech/substrate/", package = "substrate-rpc" }
|
substrate-rpc = { git = "https://github.com/paritytech/substrate/", package = "substrate-rpc" }
|
||||||
substrate-primitives = { git = "https://github.com/paritytech/substrate/", package = "substrate-primitives" }
|
substrate-primitives = { git = "https://github.com/paritytech/substrate/", package = "substrate-primitives" }
|
||||||
transaction_pool = { git = "https://github.com/paritytech/substrate/", package = "substrate-transaction-pool" }
|
transaction_pool = { git = "https://github.com/paritytech/substrate/", package = "substrate-transaction-pool" }
|
||||||
tokio = "0.1.21"
|
|
||||||
url = "1.7"
|
url = "1.7"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
env_logger = "0.6"
|
||||||
node_runtime = { git = "https://github.com/paritytech/substrate/", package = "node-runtime" }
|
node_runtime = { git = "https://github.com/paritytech/substrate/", package = "node-runtime" }
|
||||||
srml_balances = { git = "https://github.com/paritytech/substrate/", package = "srml-balances" }
|
srml_balances = { git = "https://github.com/paritytech/substrate/", package = "srml-balances" }
|
||||||
substrate-keyring = { git = "https://github.com/paritytech/substrate/", package = "substrate-keyring" }
|
substrate-keyring = { git = "https://github.com/paritytech/substrate/", package = "substrate-keyring" }
|
||||||
|
tokio = "0.1"
|
||||||
|
|||||||
+7
-9
@@ -20,16 +20,14 @@ use substrate_primitives::crypto::SecretStringError;
|
|||||||
|
|
||||||
#[derive(Debug, derive_more::From)]
|
#[derive(Debug, derive_more::From)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
Io(IoError),
|
Io(IoError),
|
||||||
Rpc(RpcError),
|
Rpc(RpcError),
|
||||||
SecretString(SecretStringError),
|
SecretString(SecretStringError),
|
||||||
Other(String),
|
Other(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&str> for Error {
|
impl From<&str> for Error {
|
||||||
fn from(error: &str) -> Self {
|
fn from(error: &str) -> Self {
|
||||||
Error::Other(error.into())
|
Error::Other(error.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
|
||||||
+64
-11
@@ -14,10 +14,12 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with substrate-subxt. If not, see <http://www.gnu.org/licenses/>.
|
// along with substrate-subxt. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use crate::error::Result;
|
|
||||||
use futures::future::Future;
|
use futures::future::Future;
|
||||||
use jsonrpc_core_client::transports::ws;
|
use jsonrpc_core_client::transports::ws;
|
||||||
use parity_codec::Codec;
|
use parity_codec::{
|
||||||
|
Codec,
|
||||||
|
Decode,
|
||||||
|
};
|
||||||
|
|
||||||
use runtime_primitives::traits::SignedExtension;
|
use runtime_primitives::traits::SignedExtension;
|
||||||
use substrate_primitives::Pair;
|
use substrate_primitives::Pair;
|
||||||
@@ -40,7 +42,7 @@ pub fn submit<T, P, C, E, SE>(
|
|||||||
signer: P,
|
signer: P,
|
||||||
call: C,
|
call: C,
|
||||||
extra: E,
|
extra: E,
|
||||||
) -> Result<ExtrinsicSuccess<T>>
|
) -> impl Future<Item = ExtrinsicSuccess<T>, Error = error::Error>
|
||||||
where
|
where
|
||||||
T: srml_system::Trait,
|
T: srml_system::Trait,
|
||||||
P: Pair,
|
P: Pair,
|
||||||
@@ -50,26 +52,65 @@ where
|
|||||||
E: Fn(T::Index) -> SE + Send + 'static,
|
E: Fn(T::Index) -> SE + Send + 'static,
|
||||||
SE: SignedExtension + 'static,
|
SE: SignedExtension + 'static,
|
||||||
{
|
{
|
||||||
let submit = ws::connect(url.as_str())
|
ws::connect(url.as_str())
|
||||||
.expect("Url is a valid url; qed")
|
.expect("Url is a valid url; qed")
|
||||||
.map_err(Into::into)
|
.map_err(Into::into)
|
||||||
.and_then(|rpc: rpc::Rpc<T, C, P, E, SE>| {
|
.and_then(|rpc: rpc::Rpc<T, C, P, E, SE>| {
|
||||||
rpc.create_and_submit_extrinsic(signer, call, extra)
|
rpc.create_and_submit_extrinsic(signer, call, extra)
|
||||||
});
|
})
|
||||||
|
}
|
||||||
|
|
||||||
let mut rt = tokio::runtime::Runtime::new()?;
|
/// Fetches a storage key from a substrate node.
|
||||||
rt.block_on(submit)
|
pub fn fetch<T: srml_system::Trait, P, C, E, SE, V: Decode>(
|
||||||
|
url: &Url,
|
||||||
|
key: Vec<u8>,
|
||||||
|
) -> impl Future<Item = Option<V>, Error = error::Error> {
|
||||||
|
ws::connect(url.as_str())
|
||||||
|
.expect("Url is a valid url; qed")
|
||||||
|
.map_err(Into::into)
|
||||||
|
.and_then(|rpc: rpc::Rpc<T, P, C, E, SE>| rpc.fetch::<V>(key))
|
||||||
|
.map_err(Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fetches a storage key from a substrate node
|
||||||
|
pub fn fetch_or<T: srml_system::Trait, P, C, E, SE, V: Decode>(
|
||||||
|
url: &Url,
|
||||||
|
key: Vec<u8>,
|
||||||
|
default: V,
|
||||||
|
) -> impl Future<Item = V, Error = error::Error> {
|
||||||
|
fetch::<T, P, C, E, SE, V>(url, key).map(|value| value.unwrap_or(default))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fetches a storage key from a substrate node.
|
||||||
|
pub fn fetch_or_default<T: srml_system::Trait, P, C, E, SE, V: Decode + Default>(
|
||||||
|
url: &Url,
|
||||||
|
key: Vec<u8>,
|
||||||
|
) -> impl Future<Item = V, Error = error::Error> {
|
||||||
|
fetch::<T, P, C, E, SE, V>(url, key).map(|value| value.unwrap_or_default())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub mod tests {
|
pub mod tests {
|
||||||
use node_runtime::Runtime;
|
use node_runtime::Runtime;
|
||||||
use runtime_primitives::generic::Era;
|
use runtime_primitives::generic::Era;
|
||||||
|
use runtime_support::StorageMap;
|
||||||
use substrate_primitives::crypto::Pair as _;
|
use substrate_primitives::crypto::Pair as _;
|
||||||
|
|
||||||
#[test] #[ignore] // requires locally running substrate node
|
fn run<F>(f: F) -> Result<F::Item, F::Error>
|
||||||
|
where
|
||||||
|
F: futures::Future + Send + 'static,
|
||||||
|
F::Item: Send + 'static,
|
||||||
|
F::Error: Send + 'static,
|
||||||
|
{
|
||||||
|
let mut rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
|
rt.block_on(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore] // requires locally running substrate node
|
||||||
fn node_runtime_balance_transfer() {
|
fn node_runtime_balance_transfer() {
|
||||||
let url = url::Url::parse("ws://localhost:9944").unwrap();
|
env_logger::try_init().ok();
|
||||||
|
let url = url::Url::parse("ws://127.0.0.1:9944").unwrap();
|
||||||
let signer = substrate_keyring::AccountKeyring::Alice.pair();
|
let signer = substrate_keyring::AccountKeyring::Alice.pair();
|
||||||
|
|
||||||
let dest = substrate_keyring::AccountKeyring::Bob.pair().public();
|
let dest = substrate_keyring::AccountKeyring::Bob.pair().public();
|
||||||
@@ -85,7 +126,19 @@ pub mod tests {
|
|||||||
srml_balances::TakeFees::<Runtime>::from(0),
|
srml_balances::TakeFees::<Runtime>::from(0),
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
let result = super::submit::<Runtime, _, _, _, _>(&url, signer, call, extra);
|
let future = super::submit::<Runtime, _, _, _, _>(&url, signer, call, extra);
|
||||||
assert!(result.is_ok())
|
run(future).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[ignore] // requires locally running substrate node
|
||||||
|
fn node_runtime_fetch_account_balance() {
|
||||||
|
env_logger::try_init().ok();
|
||||||
|
let url = url::Url::parse("ws://127.0.0.1:9944").unwrap();
|
||||||
|
let account = substrate_keyring::AccountKeyring::Alice.pair().public();
|
||||||
|
let key = <srml_balances::FreeBalance<Runtime>>::key_for(&account);
|
||||||
|
type Balance = <Runtime as srml_balances::Trait>::Balance;
|
||||||
|
let future = super::fetch::<Runtime, (), (), (), (), Balance>(&url, key);
|
||||||
|
run(future).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+59
-19
@@ -14,31 +14,60 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with substrate-subxt. If not, see <http://www.gnu.org/licenses/>.
|
// along with substrate-subxt. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use crate::{error::Error, ExtrinsicSuccess};
|
use crate::{
|
||||||
|
error::Error,
|
||||||
|
ExtrinsicSuccess,
|
||||||
|
};
|
||||||
use futures::{
|
use futures::{
|
||||||
future::{self, Future, IntoFuture},
|
future::{
|
||||||
|
self,
|
||||||
|
Future,
|
||||||
|
IntoFuture,
|
||||||
|
},
|
||||||
stream::Stream,
|
stream::Stream,
|
||||||
};
|
};
|
||||||
use jsonrpc_core_client::{RpcChannel, RpcError, TypedSubscriptionStream};
|
use jsonrpc_core_client::{
|
||||||
|
RpcChannel,
|
||||||
|
RpcError,
|
||||||
|
TypedSubscriptionStream,
|
||||||
|
};
|
||||||
use log;
|
use log;
|
||||||
use num_traits::bounds::Bounded;
|
use num_traits::bounds::Bounded;
|
||||||
use parity_codec::{Codec, Decode, Encode};
|
use parity_codec::{
|
||||||
|
Codec,
|
||||||
|
Decode,
|
||||||
|
Encode,
|
||||||
|
};
|
||||||
|
|
||||||
use runtime_primitives::{
|
use runtime_primitives::{
|
||||||
generic::UncheckedExtrinsic,
|
generic::UncheckedExtrinsic,
|
||||||
traits::{Hash as _, SignedExtension},
|
traits::{
|
||||||
|
Hash as _,
|
||||||
|
SignedExtension,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use runtime_support::StorageMap;
|
use runtime_support::StorageMap;
|
||||||
use serde::{self, de::Error as DeError, Deserialize};
|
use serde::{
|
||||||
|
self,
|
||||||
|
de::Error as DeError,
|
||||||
|
Deserialize,
|
||||||
|
};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use substrate_primitives::{
|
use substrate_primitives::{
|
||||||
blake2_256,
|
blake2_256,
|
||||||
storage::{StorageChangeSet, StorageKey},
|
storage::{
|
||||||
twox_128, Pair,
|
StorageChangeSet,
|
||||||
|
StorageKey,
|
||||||
|
},
|
||||||
|
twox_128,
|
||||||
|
Pair,
|
||||||
};
|
};
|
||||||
use substrate_rpc::{
|
use substrate_rpc::{
|
||||||
author::AuthorClient,
|
author::AuthorClient,
|
||||||
chain::{number::NumberOrHex, ChainClient},
|
chain::{
|
||||||
|
number::NumberOrHex,
|
||||||
|
ChainClient,
|
||||||
|
},
|
||||||
state::StateClient,
|
state::StateClient,
|
||||||
};
|
};
|
||||||
use transaction_pool::txpool::watcher::Status;
|
use transaction_pool::txpool::watcher::Status;
|
||||||
@@ -106,6 +135,25 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T, C, P, E, SE> Rpc<T, C, P, E, SE>
|
||||||
|
where
|
||||||
|
T: srml_system::Trait,
|
||||||
|
{
|
||||||
|
/// Fetch a storage key
|
||||||
|
pub fn fetch<V: Decode>(
|
||||||
|
&self,
|
||||||
|
key: Vec<u8>,
|
||||||
|
) -> impl Future<Item = Option<V>, Error = RpcError> {
|
||||||
|
let storage_key = StorageKey(blake2_256(&key).to_vec());
|
||||||
|
self.state
|
||||||
|
.storage(storage_key, None)
|
||||||
|
.map(|data| {
|
||||||
|
data.map(|d| Decode::decode(&mut &d.0[..]).expect("Valid storage key"))
|
||||||
|
})
|
||||||
|
.map_err(Into::into)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<T, C, P, E, SE> Rpc<T, C, P, E, SE>
|
impl<T, C, P, E, SE> Rpc<T, C, P, E, SE>
|
||||||
where
|
where
|
||||||
T: srml_system::Trait,
|
T: srml_system::Trait,
|
||||||
@@ -122,16 +170,8 @@ where
|
|||||||
account: &T::AccountId,
|
account: &T::AccountId,
|
||||||
) -> impl Future<Item = <T as srml_system::Trait>::Index, Error = RpcError> {
|
) -> impl Future<Item = <T as srml_system::Trait>::Index, Error = RpcError> {
|
||||||
let account_nonce_key = <srml_system::AccountNonce<T>>::key_for(account);
|
let account_nonce_key = <srml_system::AccountNonce<T>>::key_for(account);
|
||||||
let storage_key = blake2_256(&account_nonce_key).to_vec();
|
self.fetch::<<T as srml_system::Trait>::Index>(account_nonce_key)
|
||||||
|
.map(|value| value.unwrap_or_default())
|
||||||
self.state
|
|
||||||
.storage(StorageKey(storage_key), None)
|
|
||||||
.map(|data| {
|
|
||||||
data.map_or(Default::default(), |d| {
|
|
||||||
Decode::decode(&mut &d.0[..]).expect("Account nonce is valid Index")
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.map_err(Into::into)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Fetch the genesis hash
|
/// Fetch the genesis hash
|
||||||
|
|||||||
Reference in New Issue
Block a user