mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-24 17:05:47 +00:00
Get it to work. (#6)
This commit is contained in:
committed by
Andrew Jones
parent
19604e8f2e
commit
be5ccc1d11
+11
-7
@@ -20,8 +20,12 @@ use metadata::Metadata;
|
|||||||
use parity_scale_codec::{
|
use parity_scale_codec::{
|
||||||
Codec,
|
Codec,
|
||||||
Decode,
|
Decode,
|
||||||
|
Encode,
|
||||||
|
};
|
||||||
|
use runtime_primitives::traits::{
|
||||||
|
SignedExtension,
|
||||||
|
StaticLookup,
|
||||||
};
|
};
|
||||||
use runtime_primitives::traits::SignedExtension;
|
|
||||||
use substrate_primitives::{
|
use substrate_primitives::{
|
||||||
storage::StorageKey,
|
storage::StorageKey,
|
||||||
Pair,
|
Pair,
|
||||||
@@ -133,11 +137,11 @@ impl<T: srml_system::Trait, SE: SignedExtension> Client<T, SE> {
|
|||||||
) -> impl Future<Item = XtBuilder<T, SE, P, E>, Error = error::Error>
|
) -> impl Future<Item = XtBuilder<T, SE, P, E>, Error = error::Error>
|
||||||
where
|
where
|
||||||
P: Pair,
|
P: Pair,
|
||||||
P::Public: Into<T::AccountId>,
|
P::Public: Into<<T::Lookup as StaticLookup>::Source>,
|
||||||
P::Signature: Codec,
|
P::Signature: Codec,
|
||||||
E: Fn(T::Index) -> SE,
|
E: Fn(T::Index) -> SE,
|
||||||
{
|
{
|
||||||
let account_id: T::AccountId = signer.public().into();
|
let account_id: <T::Lookup as StaticLookup>::Source = signer.public().into();
|
||||||
let account_nonce_key = self
|
let account_nonce_key = self
|
||||||
.metadata
|
.metadata
|
||||||
.module("System")
|
.module("System")
|
||||||
@@ -169,14 +173,14 @@ pub struct XtBuilder<T: srml_system::Trait, SE: SignedExtension, P, E> {
|
|||||||
impl<T: srml_system::Trait, SE: SignedExtension, P, E> XtBuilder<T, SE, P, E>
|
impl<T: srml_system::Trait, SE: SignedExtension, P, E> XtBuilder<T, SE, P, E>
|
||||||
where
|
where
|
||||||
P: Pair,
|
P: Pair,
|
||||||
P::Public: Into<T::AccountId>,
|
P::Public: Into<<T::Lookup as StaticLookup>::Source>,
|
||||||
P::Signature: Codec,
|
P::Signature: Codec,
|
||||||
E: Fn(T::Index) -> SE,
|
E: Fn(T::Index) -> SE,
|
||||||
{
|
{
|
||||||
pub fn submit<C: Codec + Send>(
|
pub fn submit<C: Encode + Send>(
|
||||||
&self,
|
&self,
|
||||||
call: C,
|
call: C,
|
||||||
) -> impl Future<Item = ExtrinsicSuccess<T>, Error = error::Error> {
|
) -> impl Future<Item = T::Hash, Error = error::Error> {
|
||||||
let signer = self.signer.clone();
|
let signer = self.signer.clone();
|
||||||
let nonce = self.nonce.clone();
|
let nonce = self.nonce.clone();
|
||||||
let extra = (self.extra)(nonce.clone());
|
let extra = (self.extra)(nonce.clone());
|
||||||
@@ -323,7 +327,7 @@ mod tests {
|
|||||||
let call = node_runtime::Call::Balances(transfer.clone())
|
let call = node_runtime::Call::Balances(transfer.clone())
|
||||||
.encode()
|
.encode()
|
||||||
.to_vec();
|
.to_vec();
|
||||||
let call2 = balances.call(transfer);
|
let call2 = balances.call(transfer).0;
|
||||||
assert_eq!(call, call2);
|
assert_eq!(call, call2);
|
||||||
|
|
||||||
let free_balance = <srml_balances::FreeBalance<Runtime>>::key_for(&dest);
|
let free_balance = <srml_balances::FreeBalance<Runtime>>::key_for(&dest);
|
||||||
|
|||||||
+10
-2
@@ -14,6 +14,14 @@ use std::{
|
|||||||
};
|
};
|
||||||
use substrate_primitives::storage::StorageKey;
|
use substrate_primitives::storage::StorageKey;
|
||||||
|
|
||||||
|
pub struct Encoded(pub Vec<u8>);
|
||||||
|
|
||||||
|
impl Encode for Encoded {
|
||||||
|
fn encode(&self) -> Vec<u8> {
|
||||||
|
self.0.to_owned()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Metadata {
|
pub struct Metadata {
|
||||||
modules: HashMap<String, ModuleMetadata>,
|
modules: HashMap<String, ModuleMetadata>,
|
||||||
@@ -33,10 +41,10 @@ pub struct ModuleMetadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleMetadata {
|
impl ModuleMetadata {
|
||||||
pub fn call<T: Encode>(&self, call: T) -> Vec<u8> {
|
pub fn call<T: Encode>(&self, call: T) -> Encoded {
|
||||||
let mut bytes = vec![self.index];
|
let mut bytes = vec![self.index];
|
||||||
bytes.extend(call.encode());
|
bytes.extend(call.encode());
|
||||||
bytes
|
Encoded(bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn storage(&self, key: &str) -> Option<&StorageMetadata> {
|
pub fn storage(&self, key: &str) -> Option<&StorageMetadata> {
|
||||||
|
|||||||
+106
-70
@@ -17,21 +17,12 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
error::Error,
|
error::Error,
|
||||||
metadata::Metadata,
|
metadata::Metadata,
|
||||||
ExtrinsicSuccess,
|
|
||||||
};
|
};
|
||||||
use futures::{
|
use futures::future::{
|
||||||
future::{
|
self,
|
||||||
self,
|
Future,
|
||||||
Future,
|
|
||||||
IntoFuture,
|
|
||||||
},
|
|
||||||
stream::Stream,
|
|
||||||
};
|
|
||||||
use jsonrpc_core_client::{
|
|
||||||
RpcChannel,
|
|
||||||
RpcError,
|
|
||||||
TypedSubscriptionStream,
|
|
||||||
};
|
};
|
||||||
|
use jsonrpc_core_client::RpcChannel;
|
||||||
use log;
|
use log;
|
||||||
use num_traits::bounds::Bounded;
|
use num_traits::bounds::Bounded;
|
||||||
use parity_scale_codec::{
|
use parity_scale_codec::{
|
||||||
@@ -44,8 +35,8 @@ use runtime_metadata::RuntimeMetadataPrefixed;
|
|||||||
use runtime_primitives::{
|
use runtime_primitives::{
|
||||||
generic::UncheckedExtrinsic,
|
generic::UncheckedExtrinsic,
|
||||||
traits::{
|
traits::{
|
||||||
Hash as _,
|
|
||||||
SignedExtension,
|
SignedExtension,
|
||||||
|
StaticLookup,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use serde::{
|
use serde::{
|
||||||
@@ -53,15 +44,10 @@ use serde::{
|
|||||||
de::Error as DeError,
|
de::Error as DeError,
|
||||||
Deserialize,
|
Deserialize,
|
||||||
};
|
};
|
||||||
use srml_system::EventRecord;
|
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use substrate_primitives::{
|
use substrate_primitives::{
|
||||||
blake2_256,
|
blake2_256,
|
||||||
storage::{
|
storage::StorageKey,
|
||||||
StorageChangeSet,
|
|
||||||
StorageKey,
|
|
||||||
},
|
|
||||||
twox_128,
|
|
||||||
Pair,
|
Pair,
|
||||||
};
|
};
|
||||||
use substrate_rpc::{
|
use substrate_rpc::{
|
||||||
@@ -72,7 +58,6 @@ use substrate_rpc::{
|
|||||||
},
|
},
|
||||||
state::StateClient,
|
state::StateClient,
|
||||||
};
|
};
|
||||||
use transaction_pool::txpool::watcher::Status;
|
|
||||||
|
|
||||||
/// Copy of runtime_primitives::OpaqueExtrinsic to allow a local Deserialize impl
|
/// Copy of runtime_primitives::OpaqueExtrinsic to allow a local Deserialize impl
|
||||||
#[derive(PartialEq, Eq, Clone, Default, Encode, Decode)]
|
#[derive(PartialEq, Eq, Clone, Default, Encode, Decode)]
|
||||||
@@ -171,11 +156,92 @@ impl<T: srml_system::Trait, SE: SignedExtension> Rpc<T, SE> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: srml_system::Trait, SE: SignedExtension> Rpc<T, SE> {
|
||||||
|
/// Create and submit an extrinsic and return corresponding Hash if successful
|
||||||
|
pub fn create_and_submit_extrinsic<C, P>(
|
||||||
|
self,
|
||||||
|
signer: P,
|
||||||
|
call: C,
|
||||||
|
extra: SE,
|
||||||
|
account_nonce: T::Index,
|
||||||
|
genesis_hash: T::Hash,
|
||||||
|
) -> impl Future<Item = T::Hash, Error = Error>
|
||||||
|
where
|
||||||
|
C: Encode + Send,
|
||||||
|
P: Pair,
|
||||||
|
P::Public: Into<<T::Lookup as StaticLookup>::Source>,
|
||||||
|
P::Signature: Codec,
|
||||||
|
{
|
||||||
|
let extrinsic = Self::create_and_sign_extrinsic(
|
||||||
|
&signer,
|
||||||
|
call,
|
||||||
|
extra,
|
||||||
|
account_nonce,
|
||||||
|
genesis_hash,
|
||||||
|
);
|
||||||
|
|
||||||
|
self.author
|
||||||
|
.submit_extrinsic(extrinsic.encode().into())
|
||||||
|
.map_err(Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates and signs an Extrinsic for the supplied `Call`
|
||||||
|
fn create_and_sign_extrinsic<C, P>(
|
||||||
|
signer: &P,
|
||||||
|
call: C,
|
||||||
|
extra: SE,
|
||||||
|
account_nonce: T::Index,
|
||||||
|
genesis_hash: T::Hash,
|
||||||
|
) -> UncheckedExtrinsic<<T::Lookup as StaticLookup>::Source, C, P::Signature, SE>
|
||||||
|
where
|
||||||
|
C: Encode + Send,
|
||||||
|
P: Pair,
|
||||||
|
P::Public: Into<<T::Lookup as StaticLookup>::Source>,
|
||||||
|
P::Signature: Codec,
|
||||||
|
{
|
||||||
|
log::info!(
|
||||||
|
"Creating Extrinsic with genesis hash {:?} and account nonce {:?}",
|
||||||
|
genesis_hash,
|
||||||
|
account_nonce
|
||||||
|
);
|
||||||
|
|
||||||
|
let raw_payload = (call, extra.clone(), (&genesis_hash, &genesis_hash));
|
||||||
|
let signature = raw_payload.using_encoded(|payload| {
|
||||||
|
if payload.len() > 256 {
|
||||||
|
signer.sign(&blake2_256(payload)[..])
|
||||||
|
} else {
|
||||||
|
signer.sign(payload)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
UncheckedExtrinsic::new_signed(
|
||||||
|
raw_payload.0,
|
||||||
|
signer.public().into(),
|
||||||
|
signature.into(),
|
||||||
|
extra,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
use crate::ExtrinsicSuccess;
|
||||||
|
use futures::{
|
||||||
|
future::IntoFuture,
|
||||||
|
stream::Stream,
|
||||||
|
};
|
||||||
|
use jsonrpc_core_client::TypedSubscriptionStream;
|
||||||
|
use runtime_primitives::traits::Hash;
|
||||||
|
use srml_system::EventRecord;
|
||||||
|
use substrate_primitives::{
|
||||||
|
storage::StorageChangeSet,
|
||||||
|
twox_128,
|
||||||
|
};
|
||||||
|
use transaction_pool::txpool::watcher::Status;
|
||||||
|
|
||||||
impl<T: srml_system::Trait, SE: SignedExtension> Rpc<T, SE> {
|
impl<T: srml_system::Trait, SE: SignedExtension> Rpc<T, SE> {
|
||||||
/// Subscribe to substrate System Events
|
/// Subscribe to substrate System Events
|
||||||
fn subscribe_events(
|
fn subscribe_events(
|
||||||
&self,
|
&self,
|
||||||
) -> impl Future<Item = TypedSubscriptionStream<StorageChangeSet<T::Hash>>, Error = RpcError>
|
) -> impl Future<Item = TypedSubscriptionStream<StorageChangeSet<T::Hash>>, Error = Error>
|
||||||
{
|
{
|
||||||
let events_key = b"System Events";
|
let events_key = b"System Events";
|
||||||
let storage_key = twox_128(events_key);
|
let storage_key = twox_128(events_key);
|
||||||
@@ -183,18 +249,24 @@ impl<T: srml_system::Trait, SE: SignedExtension> Rpc<T, SE> {
|
|||||||
|
|
||||||
self.state
|
self.state
|
||||||
.subscribe_storage(Some(vec![StorageKey(storage_key.to_vec())]))
|
.subscribe_storage(Some(vec![StorageKey(storage_key.to_vec())]))
|
||||||
|
.map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Submit an extrinsic, waiting for it to be finalized.
|
/// Submit an extrinsic, waiting for it to be finalized.
|
||||||
/// If successful, returns the block hash.
|
/// If successful, returns the block hash.
|
||||||
fn submit_and_watch<C, P>(
|
fn submit_and_watch<C, P>(
|
||||||
self,
|
self,
|
||||||
extrinsic: UncheckedExtrinsic<T::AccountId, C, P::Signature, SE>,
|
extrinsic: UncheckedExtrinsic<
|
||||||
|
<T::Lookup as StaticLookup>::Source,
|
||||||
|
C,
|
||||||
|
P::Signature,
|
||||||
|
SE,
|
||||||
|
>,
|
||||||
) -> impl Future<Item = T::Hash, Error = Error>
|
) -> impl Future<Item = T::Hash, Error = Error>
|
||||||
where
|
where
|
||||||
C: Codec + Send,
|
C: Encode + Send,
|
||||||
P: Pair,
|
P: Pair,
|
||||||
P::Public: Into<T::AccountId>,
|
P::Public: Into<<T::Lookup as StaticLookup>::Source>,
|
||||||
P::Signature: Codec,
|
P::Signature: Codec,
|
||||||
{
|
{
|
||||||
self.author
|
self.author
|
||||||
@@ -204,7 +276,8 @@ impl<T: srml_system::Trait, SE: SignedExtension> Rpc<T, SE> {
|
|||||||
stream
|
stream
|
||||||
.filter_map(|status| {
|
.filter_map(|status| {
|
||||||
match status {
|
match status {
|
||||||
Status::Future | Status::Ready | Status::Broadcast(_) => None, // ignore in progress extrinsic for now
|
// ignore in progress extrinsic for now
|
||||||
|
Status::Future | Status::Ready | Status::Broadcast(_) => None,
|
||||||
Status::Finalized(block_hash) => Some(Ok(block_hash)),
|
Status::Finalized(block_hash) => Some(Ok(block_hash)),
|
||||||
Status::Usurped(_) => Some(Err("Extrinsic Usurped".into())),
|
Status::Usurped(_) => Some(Err("Extrinsic Usurped".into())),
|
||||||
Status::Dropped => Some(Err("Extrinsic Dropped".into())),
|
Status::Dropped => Some(Err("Extrinsic Dropped".into())),
|
||||||
@@ -223,7 +296,8 @@ impl<T: srml_system::Trait, SE: SignedExtension> Rpc<T, SE> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create and submit an extrinsic and return corresponding Event if successful
|
/// Create and submit an extrinsic and return corresponding Event if successful
|
||||||
pub fn create_and_submit_extrinsic<C, P>(
|
#[allow(unused)]
|
||||||
|
pub fn create_and_watch_extrinsic<C, P>(
|
||||||
self,
|
self,
|
||||||
signer: P,
|
signer: P,
|
||||||
call: C,
|
call: C,
|
||||||
@@ -232,22 +306,21 @@ impl<T: srml_system::Trait, SE: SignedExtension> Rpc<T, SE> {
|
|||||||
genesis_hash: T::Hash,
|
genesis_hash: T::Hash,
|
||||||
) -> impl Future<Item = ExtrinsicSuccess<T>, Error = Error>
|
) -> impl Future<Item = ExtrinsicSuccess<T>, Error = Error>
|
||||||
where
|
where
|
||||||
C: Codec + Send,
|
C: Encode + Send,
|
||||||
P: Pair,
|
P: Pair,
|
||||||
P::Public: Into<T::AccountId>,
|
P::Public: Into<<T::Lookup as StaticLookup>::Source>,
|
||||||
P::Signature: Codec,
|
P::Signature: Codec,
|
||||||
{
|
{
|
||||||
let events = self.subscribe_events().map_err(Into::into);
|
let events = self.subscribe_events().map_err(Into::into);
|
||||||
events.and_then(move |events| {
|
events.and_then(move |events| {
|
||||||
let extrinsic = Self::create_and_sign_extrinsic(
|
let extrinsic = Self::create_and_sign_extrinsic(
|
||||||
account_nonce,
|
|
||||||
call,
|
|
||||||
genesis_hash,
|
|
||||||
&signer,
|
&signer,
|
||||||
|
call,
|
||||||
extra,
|
extra,
|
||||||
|
account_nonce,
|
||||||
|
genesis_hash,
|
||||||
);
|
);
|
||||||
let ext_hash = T::Hashing::hash_of(&extrinsic);
|
let ext_hash = T::Hashing::hash_of(&extrinsic);
|
||||||
|
|
||||||
log::info!("Submitting Extrinsic `{:?}`", ext_hash);
|
log::info!("Submitting Extrinsic `{:?}`", ext_hash);
|
||||||
|
|
||||||
let chain = self.chain.clone();
|
let chain = self.chain.clone();
|
||||||
@@ -274,43 +347,6 @@ impl<T: srml_system::Trait, SE: SignedExtension> Rpc<T, SE> {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates and signs an Extrinsic for the supplied `Call`
|
|
||||||
fn create_and_sign_extrinsic<C, P>(
|
|
||||||
index: T::Index,
|
|
||||||
function: C,
|
|
||||||
genesis_hash: T::Hash,
|
|
||||||
signer: &P,
|
|
||||||
extra: SE,
|
|
||||||
) -> UncheckedExtrinsic<T::AccountId, C, P::Signature, SE>
|
|
||||||
where
|
|
||||||
C: Encode + Send,
|
|
||||||
P: Pair,
|
|
||||||
P::Public: Into<T::AccountId>,
|
|
||||||
P::Signature: Codec,
|
|
||||||
{
|
|
||||||
log::info!(
|
|
||||||
"Creating Extrinsic with genesis hash {:?} and account nonce {:?}",
|
|
||||||
genesis_hash,
|
|
||||||
index
|
|
||||||
);
|
|
||||||
|
|
||||||
let raw_payload = (function, extra.clone(), genesis_hash);
|
|
||||||
let signature = raw_payload.using_encoded(|payload| {
|
|
||||||
if payload.len() > 256 {
|
|
||||||
signer.sign(&blake2_256(payload)[..])
|
|
||||||
} else {
|
|
||||||
signer.sign(payload)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
UncheckedExtrinsic::new_signed(
|
|
||||||
raw_payload.0,
|
|
||||||
signer.public().into(),
|
|
||||||
signature.into(),
|
|
||||||
extra,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Waits for events for the block triggered by the extrinsic
|
/// Waits for events for the block triggered by the extrinsic
|
||||||
|
|||||||
Reference in New Issue
Block a user