Get it to work. (#6)

This commit is contained in:
David Craven
2019-08-08 17:01:07 +02:00
committed by Andrew Jones
parent 19604e8f2e
commit be5ccc1d11
3 changed files with 127 additions and 79 deletions
+11 -7
View File
@@ -20,8 +20,12 @@ use metadata::Metadata;
use parity_scale_codec::{
Codec,
Decode,
Encode,
};
use runtime_primitives::traits::{
SignedExtension,
StaticLookup,
};
use runtime_primitives::traits::SignedExtension;
use substrate_primitives::{
storage::StorageKey,
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>
where
P: Pair,
P::Public: Into<T::AccountId>,
P::Public: Into<<T::Lookup as StaticLookup>::Source>,
P::Signature: Codec,
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
.metadata
.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>
where
P: Pair,
P::Public: Into<T::AccountId>,
P::Public: Into<<T::Lookup as StaticLookup>::Source>,
P::Signature: Codec,
E: Fn(T::Index) -> SE,
{
pub fn submit<C: Codec + Send>(
pub fn submit<C: Encode + Send>(
&self,
call: C,
) -> impl Future<Item = ExtrinsicSuccess<T>, Error = error::Error> {
) -> impl Future<Item = T::Hash, Error = error::Error> {
let signer = self.signer.clone();
let nonce = self.nonce.clone();
let extra = (self.extra)(nonce.clone());
@@ -323,7 +327,7 @@ mod tests {
let call = node_runtime::Call::Balances(transfer.clone())
.encode()
.to_vec();
let call2 = balances.call(transfer);
let call2 = balances.call(transfer).0;
assert_eq!(call, call2);
let free_balance = <srml_balances::FreeBalance<Runtime>>::key_for(&dest);
+10 -2
View File
@@ -14,6 +14,14 @@ use std::{
};
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)]
pub struct Metadata {
modules: HashMap<String, ModuleMetadata>,
@@ -33,10 +41,10 @@ pub struct 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];
bytes.extend(call.encode());
bytes
Encoded(bytes)
}
pub fn storage(&self, key: &str) -> Option<&StorageMetadata> {
+106 -70
View File
@@ -17,21 +17,12 @@
use crate::{
error::Error,
metadata::Metadata,
ExtrinsicSuccess,
};
use futures::{
future::{
self,
Future,
IntoFuture,
},
stream::Stream,
};
use jsonrpc_core_client::{
RpcChannel,
RpcError,
TypedSubscriptionStream,
use futures::future::{
self,
Future,
};
use jsonrpc_core_client::RpcChannel;
use log;
use num_traits::bounds::Bounded;
use parity_scale_codec::{
@@ -44,8 +35,8 @@ use runtime_metadata::RuntimeMetadataPrefixed;
use runtime_primitives::{
generic::UncheckedExtrinsic,
traits::{
Hash as _,
SignedExtension,
StaticLookup,
},
};
use serde::{
@@ -53,15 +44,10 @@ use serde::{
de::Error as DeError,
Deserialize,
};
use srml_system::EventRecord;
use std::convert::TryInto;
use substrate_primitives::{
blake2_256,
storage::{
StorageChangeSet,
StorageKey,
},
twox_128,
storage::StorageKey,
Pair,
};
use substrate_rpc::{
@@ -72,7 +58,6 @@ use substrate_rpc::{
},
state::StateClient,
};
use transaction_pool::txpool::watcher::Status;
/// Copy of runtime_primitives::OpaqueExtrinsic to allow a local Deserialize impl
#[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> {
/// Subscribe to substrate System Events
fn subscribe_events(
&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 storage_key = twox_128(events_key);
@@ -183,18 +249,24 @@ impl<T: srml_system::Trait, SE: SignedExtension> Rpc<T, SE> {
self.state
.subscribe_storage(Some(vec![StorageKey(storage_key.to_vec())]))
.map_err(Into::into)
}
/// Submit an extrinsic, waiting for it to be finalized.
/// If successful, returns the block hash.
fn submit_and_watch<C, P>(
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>
where
C: Codec + Send,
C: Encode + Send,
P: Pair,
P::Public: Into<T::AccountId>,
P::Public: Into<<T::Lookup as StaticLookup>::Source>,
P::Signature: Codec,
{
self.author
@@ -204,7 +276,8 @@ impl<T: srml_system::Trait, SE: SignedExtension> Rpc<T, SE> {
stream
.filter_map(|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::Usurped(_) => Some(Err("Extrinsic Usurped".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
pub fn create_and_submit_extrinsic<C, P>(
#[allow(unused)]
pub fn create_and_watch_extrinsic<C, P>(
self,
signer: P,
call: C,
@@ -232,22 +306,21 @@ impl<T: srml_system::Trait, SE: SignedExtension> Rpc<T, SE> {
genesis_hash: T::Hash,
) -> impl Future<Item = ExtrinsicSuccess<T>, Error = Error>
where
C: Codec + Send,
C: Encode + Send,
P: Pair,
P::Public: Into<T::AccountId>,
P::Public: Into<<T::Lookup as StaticLookup>::Source>,
P::Signature: Codec,
{
let events = self.subscribe_events().map_err(Into::into);
events.and_then(move |events| {
let extrinsic = Self::create_and_sign_extrinsic(
account_nonce,
call,
genesis_hash,
&signer,
call,
extra,
account_nonce,
genesis_hash,
);
let ext_hash = T::Hashing::hash_of(&extrinsic);
log::info!("Submitting Extrinsic `{:?}`", ext_hash);
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