Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Fix transaction submission for hex #259

Merged
merged 2 commits into from
Jun 28, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions substrate/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ macro_rules! map {
)
}

use rstd::prelude::*;
use rstd::ops::Deref;

#[cfg(feature = "std")]
pub mod bytes;
Expand All @@ -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<u8>`.
#[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<u8>);

impl From<Vec<u8>> for Bytes {
fn from(s: Vec<u8>) -> Self { Bytes(s) }
}

impl Deref for Bytes {
type Target = [u8];
fn deref(&self) -> &[u8] { &self.0[..] }
}
1 change: 1 addition & 0 deletions substrate/rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
Expand Down
5 changes: 5 additions & 0 deletions substrate/rpc/src/author/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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"),
Expand Down
15 changes: 12 additions & 3 deletions substrate/rpc/src/author/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -35,8 +37,11 @@ build_rpc_trait! {
/// Substrate authoring RPC API
pub trait AuthorApi<Hash, Extrinsic> {
/// Submit extrinsic for inclusion in block.
#[rpc(name = "author_submitRichExtrinsic")]
fn submit_rich_extrinsic(&self, Extrinsic) -> Result<Hash>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about naming scheme choosen here. I kinda understand why it is "rich" extrinsic, but maybe it is better to leave it as "submit_extrinsic" and make another procedure call "submit_raw_extrinsic"?

Or are we constrained by backward compatibility here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

most practical uses of substrate will be easier to use with the raw variant, so it makes sense to me to optimize the API a bit for it.

/// Submit hex-encoded extrinsic for inclusion in block.
#[rpc(name = "author_submitExtrinsic")]
fn submit_extrinsic(&self, Extrinsic) -> Result<Hash>;
fn submit_extrinsic(&self, Bytes) -> Result<Hash>;
}
}

Expand All @@ -55,16 +60,20 @@ impl<B, E, Block: BlockT, P> Author<B, E, Block, P> {
}
}


impl<B, E, Block, P, Ex, Hash> AuthorApi<Hash, Ex> for Author<B, E, Block, P> where
B: client::backend::Backend<Block> + Send + Sync + 'static,
E: client::CallExecutor<Block> + Send + Sync + 'static,
Block: BlockT + 'static,
client::error::Error: From<<<B as client::backend::Backend<Block>>::State as state_machine::backend::Backend>::Error>,
P: ExtrinsicPool<Ex, generic::BlockId<Block>, Hash>,
P::Error: 'static,
Ex: Slicable,
{
fn submit_extrinsic(&self, xt: Ex) -> Result<Hash> {
fn submit_extrinsic(&self, xt: Bytes) -> Result<Hash> {
self.submit_rich_extrinsic(Ex::decode(&mut &xt[..]).ok_or(error::Error::from(error::ErrorKind::BadFormat))?)
}

fn submit_rich_extrinsic(&self, xt: Ex) -> Result<Hash> {
let best_block_hash = self.client.info().unwrap().chain.best_hash;
self.pool
.submit(generic::BlockId::hash(best_block_hash), vec![xt])
Expand Down
20 changes: 18 additions & 2 deletions substrate/rpc/src/author/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
);
}
1 change: 1 addition & 0 deletions substrate/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down