Skip to content

Commit

Permalink
support rpc module ext and format code (paritytech#24)
Browse files Browse the repository at this point in the history
* fix genesis config

* update runtime privcall

* add cargo.lock in runtime/wasm

* add rpc module and format code

* fix spell error
  • Loading branch information
toxotguo authored and gguoss committed Sep 14, 2018
1 parent bc2945c commit e6c5902
Show file tree
Hide file tree
Showing 10 changed files with 396 additions and 111 deletions.
27 changes: 27 additions & 0 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ version = "0.1.0"
authors = ["Chainpool <https://www.chainx.org>"]

[dependencies]
jsonrpc-macros = { git="https://github.com/paritytech/jsonrpc.git" }
substrate-network = { git = "https://github.com/chainx-org/substrate" }
substrate-network-libp2p = { git = "https://github.com/chainx-org/substrate" }
substrate-runtime-primitives = { git = "https://github.com/chainx-org/substrate" }
Expand Down Expand Up @@ -52,4 +53,5 @@ members = [
"rpc",
"api",
"test",
"fxck"
]
13 changes: 13 additions & 0 deletions rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,17 @@ authors = ["Chainpool <http://www.chainx.org>"]

[dependencies]
substrate-rpc = { git = "https://github.com/chainx-org/substrate" }
jsonrpc-core = { git="https://github.com/paritytech/jsonrpc.git" }
jsonrpc-http-server = { git = "https://github.com/paritytech/jsonrpc.git" }
jsonrpc-pubsub = { git = "https://github.com/paritytech/jsonrpc.git" }
jsonrpc-ws-server = { git = "https://github.com/paritytech/jsonrpc.git" }
jsonrpc-macros = { git="https://github.com/paritytech/jsonrpc.git" }
substrate-runtime-primitives = { git = "https://github.com/chainx-org/substrate" }
substrate-primitives = { git = "https://github.com/chainx-org/substrate" }
substrate-rpc-servers = { git = "https://github.com/chainx-org/substrate" }
substrate-client = { git = "https://github.com/chainx-org/substrate" }
chainx-api = { path = "../api" }
log = "0.3"
serde = "1.0"
tokio = "0.1.7"
error-chain = "0.12"
41 changes: 41 additions & 0 deletions rpc/src/chainext/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use client;
use jsonrpc_core as rpccore;

pub fn unimplemented() -> rpccore::Error {
rpccore::Error {
code: rpccore::ErrorCode::ServerError(1),
message: "Not implemented yet".into(),
data: None,
}
}

pub fn internal<E: ::std::fmt::Debug>(e: E) -> rpccore::Error {
warn!("Unknown error: {:?}", e);
rpccore::Error {
code: rpccore::ErrorCode::InternalError,
message: "Unknown error occured".into(),
data: Some(format!("{:?}", e).into()),
}
}

error_chain! {
links {
Client(client::error::Error, client::error::ErrorKind) #[doc = "Client error"];
}
errors {
/// Not implemented yet
Unimplemented {
description("not yet implemented"),
display("Method Not Implemented"),
}
}
}

impl From<Error> for rpccore::Error {
fn from(e: Error) -> Self {
match e {
Error(ErrorKind::Unimplemented, _) => unimplemented(),
e => internal(e),
}
}
}
56 changes: 56 additions & 0 deletions rpc/src/chainext/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use jsonrpc_macros::Trailing;
use primitives::{KeccakHasher, RlpCodec};
use runtime_primitives::generic::{BlockId, SignedBlock};
use runtime_primitives::traits::{Block as BlockT, Header, NumberFor};

use client::{self, Client};
use std::sync::Arc;
use tokio::runtime::TaskExecutor;

mod error;
use self::error::Result;

build_rpc_trait! {
pub trait ChainApiExt<Hash, Header, Number, Extrinsic> {

#[rpc(name = "chainext_getBlockByNumber")]
fn block_info(&self, Trailing<Number>) -> Result<Option<SignedBlock<Header, Extrinsic, Hash>>>;
}
}

pub struct ChainExt<B, E, Block: BlockT> {
client: Arc<Client<B, E, Block>>,
}

impl<B, E, Block: BlockT> ChainExt<B, E, Block> {
pub fn new(client: Arc<Client<B, E, Block>>, _executor: TaskExecutor) -> Self {
Self { client }
}
}

impl<B, E, Block> ChainApiExt<Block::Hash, Block::Header, NumberFor<Block>, Block::Extrinsic>
for ChainExt<B, E, Block>
where
Block: BlockT + 'static,
B: client::backend::Backend<Block, KeccakHasher, RlpCodec> + Send + Sync + 'static,
E: client::CallExecutor<Block, KeccakHasher, RlpCodec> + Send + Sync + 'static,
{
fn block_info(
&self,
number: Trailing<NumberFor<Block>>,
) -> Result<Option<SignedBlock<Block::Header, Block::Extrinsic, Block::Hash>>> {
let hash = match number.into() {
None => Some(self.client.info()?.chain.best_hash),
Some(number) => self
.client
.header(&BlockId::number(number))?
.map(|h| h.hash()),
};
let block_hash = match hash {
None => self.client.info()?.chain.best_hash,
Some(h) => h,
};

Ok(self.client.block(&BlockId::Hash(block_hash))?)
}
}
25 changes: 23 additions & 2 deletions rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,28 @@ extern crate substrate_rpc as rpc;
#[macro_use]
extern crate log;

extern crate chainx_api;
extern crate jsonrpc_core;
extern crate jsonrpc_http_server as http;
extern crate jsonrpc_pubsub as pubsub;
extern crate jsonrpc_ws_server as ws;
extern crate serde;
extern crate substrate_client as client;
extern crate substrate_primitives as primitives;
extern crate substrate_rpc;
pub extern crate substrate_rpc as apis;
extern crate substrate_rpc_servers as rpc_server;
extern crate substrate_runtime_primitives as runtime_primitives;
extern crate tokio;
#[macro_use]
extern crate error_chain;

#[macro_use]
extern crate jsonrpc_macros;

pub mod chainext;
pub mod servers;

use std::io;
use std::net::SocketAddr;

Expand Down Expand Up @@ -49,8 +71,7 @@ where
{
Ok(match address {
Some(mut address) => Some(start(&address).or_else(|e| match e.kind() {
io::ErrorKind::AddrInUse |
io::ErrorKind::PermissionDenied => {
io::ErrorKind::AddrInUse | io::ErrorKind::PermissionDenied => {
warn!("Unable to bind server to {}. Trying random port.", address);
address.set_port(0);
start(&address)
Expand Down
79 changes: 79 additions & 0 deletions rpc/src/servers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
//! chainx RPC servers.

use apis;
use http;
use pubsub;
use runtime_primitives;
use runtime_primitives::traits::{Block as BlockT, NumberFor};
use serde;
use std;
use std::io;
use ws;

use chainext;

type Metadata = apis::metadata::Metadata;
type RpcHandler = pubsub::PubSubHandler<Metadata>;
pub type HttpServer = http::Server;
pub type WsServer = ws::Server;

/// Construct rpc `IoHandler`
pub fn rpc_handler<Block: BlockT, ExHash, PendingExtrinsics, S, C, CE, A, Y>(
state: S,
chain: C,
chainext: CE,
author: A,
system: Y,
) -> RpcHandler
where
Block: BlockT + 'static,
ExHash: Send
+ Sync
+ 'static
+ runtime_primitives::Serialize
+ runtime_primitives::DeserializeOwned,
PendingExtrinsics: serde::Serialize + serde::de::DeserializeOwned + Send + Sync + 'static,
S: apis::state::StateApi<Block::Hash, Metadata = Metadata>,
C: apis::chain::ChainApi<
Block::Hash,
Block::Header,
NumberFor<Block>,
Block::Extrinsic,
Metadata = Metadata,
>,
CE: chainext::ChainApiExt<Block::Hash, Block::Header, NumberFor<Block>, Block::Extrinsic>,
A: apis::author::AuthorApi<ExHash, Block::Extrinsic, PendingExtrinsics, Metadata = Metadata>,
Y: apis::system::SystemApi,
{
let mut io = pubsub::PubSubHandler::default();
io.extend_with(state.to_delegate());
io.extend_with(chain.to_delegate());
io.extend_with(chainext.to_delegate());
io.extend_with(author.to_delegate());
io.extend_with(system.to_delegate());
io
}

/// Start HTTP server listening on given address.
pub fn start_http(addr: &std::net::SocketAddr, io: RpcHandler) -> io::Result<http::Server> {
http::ServerBuilder::new(io)
.threads(4)
.rest_api(http::RestApi::Unsecure)
.cors(http::DomainsValidation::Disabled)
.start_http(addr)
}

/// Start WS server listening on given address.
pub fn start_ws(addr: &std::net::SocketAddr, io: RpcHandler) -> io::Result<ws::Server> {
ws::ServerBuilder::with_meta_extractor(io, |context: &ws::RequestContext| {
Metadata::new(context.sender())
}).start(addr)
.map_err(|err| match err {
ws::Error(ws::ErrorKind::Io(io), _) => io,
ws::Error(ws::ErrorKind::ConnectionClosed, _) => io::ErrorKind::BrokenPipe.into(),
ws::Error(e, _) => {
error!("{}", e);
io::ErrorKind::Other.into()
}
})
}
2 changes: 2 additions & 0 deletions runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ use chainx_primitives::InherentData;
use runtime_primitives::generic;
use version::RuntimeVersion;

//pub use chainx_primitives::Header;

pub fn inherent_extrinsics(data: InherentData) -> Vec<UncheckedExtrinsic> {
let make_inherent = |function| UncheckedExtrinsic::new(
Extrinsic {
Expand Down
Loading

0 comments on commit e6c5902

Please sign in to comment.