diff --git a/Cargo.lock b/Cargo.lock index 875610ebe07e5..cf1276caf781c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2279,6 +2279,7 @@ dependencies = [ "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "substrate-client 0.1.0", + "substrate-codec 0.1.0", "substrate-executor 0.1.0", "substrate-extrinsic-pool 0.1.0", "substrate-primitives 0.1.0", diff --git a/substrate/primitives/src/lib.rs b/substrate/primitives/src/lib.rs index 68306b01e80c0..5fd4e1a642636 100644 --- a/substrate/primitives/src/lib.rs +++ b/substrate/primitives/src/lib.rs @@ -61,6 +61,8 @@ macro_rules! map { ) } +use rstd::prelude::*; +use rstd::ops::Deref; #[cfg(feature = "std")] pub mod bytes; @@ -87,3 +89,17 @@ pub type AuthorityId = [u8; 32]; /// A 512-bit value interpreted as a signature. pub type Signature = hash::H512; + +/// Hex-serialised shim for `Vec`. +#[derive(PartialEq, Eq, Clone)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug, Hash, PartialOrd, Ord))] +pub struct Bytes(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec); + +impl From> for Bytes { + fn from(s: Vec) -> Self { Bytes(s) } +} + +impl Deref for Bytes { + type Target = [u8]; + fn deref(&self) -> &[u8] { &self.0[..] } +} \ No newline at end of file diff --git a/substrate/rpc/Cargo.toml b/substrate/rpc/Cargo.toml index fb8bea65a9054..d78f69d925bab 100644 --- a/substrate/rpc/Cargo.toml +++ b/substrate/rpc/Cargo.toml @@ -10,6 +10,7 @@ jsonrpc-macros = { git="https://github.com/paritytech/jsonrpc.git" } jsonrpc-pubsub = { git="https://github.com/paritytech/jsonrpc.git" } log = "0.3" parking_lot = "0.4" +substrate-codec = { path = "../codec" } substrate-client = { path = "../client" } substrate-executor = { path = "../executor" } substrate-extrinsic-pool = { path = "../extrinsic-pool" } diff --git a/substrate/rpc/src/author/error.rs b/substrate/rpc/src/author/error.rs index 5f7b9a82b282a..ea6a713cd7893 100644 --- a/substrate/rpc/src/author/error.rs +++ b/substrate/rpc/src/author/error.rs @@ -24,6 +24,11 @@ error_chain! { Pool(txpool::Error, txpool::ErrorKind) #[doc = "Pool error"]; } errors { + /// Incorrect transaction format. + BadFormat { + description("bad format"), + display("Invalid transaction format"), + } /// Not implemented yet Unimplemented { description("not yet implemented"), diff --git a/substrate/rpc/src/author/mod.rs b/substrate/rpc/src/author/mod.rs index fd29fa8adc821..1d916b4e29c6d 100644 --- a/substrate/rpc/src/author/mod.rs +++ b/substrate/rpc/src/author/mod.rs @@ -20,7 +20,9 @@ use std::sync::Arc; use client::{self, Client}; use extrinsic_pool::api::{Error, ExtrinsicPool}; +use codec::Slicable; +use primitives::Bytes; use runtime_primitives::{generic, traits::Block as BlockT}; use state_machine; @@ -35,8 +37,11 @@ build_rpc_trait! { /// Substrate authoring RPC API pub trait AuthorApi { /// Submit extrinsic for inclusion in block. + #[rpc(name = "author_submitRichExtrinsic")] + fn submit_rich_extrinsic(&self, Extrinsic) -> Result; + /// Submit hex-encoded extrinsic for inclusion in block. #[rpc(name = "author_submitExtrinsic")] - fn submit_extrinsic(&self, Extrinsic) -> Result; + fn submit_extrinsic(&self, Bytes) -> Result; } } @@ -55,7 +60,6 @@ impl Author { } } - impl AuthorApi for Author where B: client::backend::Backend + Send + Sync + 'static, E: client::CallExecutor + Send + Sync + 'static, @@ -63,8 +67,13 @@ impl AuthorApi for Author wh client::error::Error: From<<>::State as state_machine::backend::Backend>::Error>, P: ExtrinsicPool, Hash>, P::Error: 'static, + Ex: Slicable, { - fn submit_extrinsic(&self, xt: Ex) -> Result { + fn submit_extrinsic(&self, xt: Bytes) -> Result { + self.submit_rich_extrinsic(Ex::decode(&mut &xt[..]).ok_or(error::Error::from(error::ErrorKind::BadFormat))?) + } + + fn submit_rich_extrinsic(&self, xt: Ex) -> Result { let best_block_hash = self.client.info().unwrap().chain.best_hash; self.pool .submit(generic::BlockId::hash(best_block_hash), vec![xt]) diff --git a/substrate/rpc/src/author/tests.rs b/substrate/rpc/src/author/tests.rs index 08757957226b2..6c5b5fb05e2b1 100644 --- a/substrate/rpc/src/author/tests.rs +++ b/substrate/rpc/src/author/tests.rs @@ -65,10 +65,26 @@ fn submit_transaction_should_not_cause_error() { }; assert_matches!( - AuthorApi::submit_extrinsic(&p, 5), + AuthorApi::submit_extrinsic(&p, u64::encode(&5).into()), Ok(1) ); assert!( - AuthorApi::submit_extrinsic(&p, 5).is_err() + AuthorApi::submit_extrinsic(&p, u64::encode(&5).into()).is_err() + ); +} + +#[test] +fn submit_rich_transaction_should_not_cause_error() { + let p = Author { + client: Arc::new(test_client::new()), + pool: Arc::new(DummyTxPool::default()), + }; + + assert_matches!( + AuthorApi::submit_rich_extrinsic(&p, 5), + Ok(1) + ); + assert!( + AuthorApi::submit_rich_extrinsic(&p, 5).is_err() ); } diff --git a/substrate/rpc/src/lib.rs b/substrate/rpc/src/lib.rs index 8cd043652ae57..f8099ec33e27e 100644 --- a/substrate/rpc/src/lib.rs +++ b/substrate/rpc/src/lib.rs @@ -21,6 +21,7 @@ extern crate jsonrpc_core as rpc; extern crate jsonrpc_pubsub; extern crate parking_lot; +extern crate substrate_codec as codec; extern crate substrate_client as client; extern crate substrate_extrinsic_pool as extrinsic_pool; extern crate substrate_primitives as primitives;