RPC & Client (#21)

* Initial version of http server.

* Refactor the structure.

* add unassigned ports info.

* Rename servers to match conventions.

* Add client crate and some proper RPC implementations.

* Style & docs.
This commit is contained in:
Tomasz Drwięga
2017-11-15 19:29:14 +01:00
committed by Robert Habermeier
parent 0ceebe6625
commit db78e5fb4c
33 changed files with 1121 additions and 34 deletions
+16
View File
@@ -0,0 +1,16 @@
[package]
name = "polkadot-rpc"
version = "0.1.0"
authors = ["Parity Technologies <admin@parity.io>"]
[dependencies]
error-chain = "0.11"
jsonrpc-core = { git="https://github.com/paritytech/jsonrpc.git" }
jsonrpc-macros = { git="https://github.com/paritytech/jsonrpc.git" }
polkadot-client = { path = "../client", version = "0.1" }
polkadot-primitives = { path = "../primitives", version = "0.1" }
polkadot-state-machine = { path = "../state_machine", version = "0.1" }
[dev-dependencies]
assert_matches = "1.1"
polkadot-contracts = { path = "../contracts", version = "0.1" }
+40
View File
@@ -0,0 +1,40 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
use rpc;
error_chain! {
errors {
/// Not implemented yet
Unimplemented {
description("not yet implemented"),
display("Method Not Implemented"),
}
}
}
impl From<Error> for rpc::Error {
fn from(e: Error) -> Self {
match e {
Error(ErrorKind::Unimplemented, _) => rpc::Error {
code: rpc::ErrorCode::ServerError(-1),
message: "Not implemented yet".into(),
data: None,
},
_ => rpc::Error::internal_error(),
}
}
}
+45
View File
@@ -0,0 +1,45 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Polkadot blockchain API.
use primitives::block;
use client;
mod error;
#[cfg(test)]
mod tests;
use self::error::{Result, ResultExt};
build_rpc_trait! {
/// Polkadot blockchain API
pub trait ChainApi {
/// Get header of a relay chain block.
#[rpc(name = "chain_getHeader")]
fn header(&self, block::HeaderHash) -> Result<Option<block::Header>>;
}
}
impl<B> ChainApi for B where
B: client::Blockchain + Send + Sync + 'static,
B::Error: ::std::error::Error + Send,
{
fn header(&self, hash: block::HeaderHash) -> Result<Option<block::Header>> {
self.header(&hash).chain_err(|| "Blockchain error")
}
}
+39
View File
@@ -0,0 +1,39 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
use super::*;
use test_helpers::Blockchain;
#[test]
fn should_return_header() {
let state = Blockchain::default();
assert_matches!(
ChainApi::header(&state, 0.into()),
Ok(Some(ref x)) if x == &block::Header {
parent_hash: 0.into(),
state_root: 0.into(),
timestamp: 0,
number: 0,
}
);
assert_matches!(
ChainApi::header(&state, 5.into()),
Ok(None)
);
}
+41
View File
@@ -0,0 +1,41 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Polkadot RPC interfaces.
#![warn(missing_docs)]
extern crate jsonrpc_core as rpc;
extern crate polkadot_client as client;
extern crate polkadot_primitives as primitives;
extern crate polkadot_state_machine as state_machine;
#[macro_use]
extern crate error_chain;
#[macro_use]
extern crate jsonrpc_macros;
#[cfg(test)]
extern crate polkadot_contracts;
#[cfg(test)]
#[macro_use]
extern crate assert_matches;
pub mod chain;
pub mod state;
#[cfg(test)]
mod test_helpers;
+45
View File
@@ -0,0 +1,45 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
use client;
use rpc;
error_chain! {
links {
Client(client::error::Error, client::error::ErrorKind) #[doc = "Client error"];
}
errors {
/// Not implemented yet
Unimplemented {
description("not implemented yet"),
display("Method Not Implemented"),
}
}
}
impl From<Error> for rpc::Error {
fn from(e: Error) -> Self {
match e {
Error(ErrorKind::Unimplemented, _) => rpc::Error {
code: rpc::ErrorCode::ServerError(-1),
message: "Not implemented yet".into(),
data: None,
},
_ => rpc::Error::internal_error(),
}
}
}
+55
View File
@@ -0,0 +1,55 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! Polkadot state API.
mod error;
#[cfg(test)]
mod tests;
use client::{self, Client};
use primitives::{block, Address, H256};
use primitives::contract::{CallData, OutData, StorageData};
use state_machine;
use self::error::Result;
build_rpc_trait! {
/// Polkadot state API
pub trait StateApi {
/// Returns a storage entry.
#[rpc(name = "state_getStorage")]
fn storage(&self, Address, H256, block::HeaderHash) -> Result<StorageData>;
/// Call a contract.
#[rpc(name = "state_call")]
fn call(&self, Address, String, CallData, block::HeaderHash) -> Result<OutData>;
}
}
impl<B, E> StateApi for Client<B, E> where
B: client::Blockchain + Send + Sync + 'static,
E: state_machine::CodeExecutor + Send + Sync + 'static,
{
fn storage(&self, address: Address, key: H256, block: block::HeaderHash) -> Result<StorageData> {
Ok(self.storage(&block, &address, &key)?)
}
fn call(&self, address: Address, method: String, data: CallData, block: block::HeaderHash) -> Result<OutData> {
Ok(self.call(&block, &address, &method, &data)?)
}
}
+42
View File
@@ -0,0 +1,42 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
use super::*;
use polkadot_contracts as contracts;
use self::error::{Error, ErrorKind};
use test_helpers::Blockchain;
#[test]
fn should_return_storage() {
let client = Client::new(Blockchain::default(), contracts::executor());
assert_matches!(
StateApi::storage(&client, 5.into(), 10.into(), 0.into()),
Ok(ref x) if x.0.is_empty()
)
}
#[test]
fn should_call_contract() {
// TODO [ToDr] Fix test after we are able to mock state.
let client = Client::new(Blockchain::default(), contracts::executor());
assert_matches!(
StateApi::call(&client, 1.into(), "balanceOf".into(), CallData(vec![1,2,3]), 0.into()),
Err(Error(ErrorKind::Client(client::error::ErrorKind::Execution(_)), _))
)
}
+44
View File
@@ -0,0 +1,44 @@
// Copyright 2017 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
use client;
use primitives::block;
/// Temporary dummy blockchain implementation for tests.
#[derive(Debug, Default)]
pub struct Blockchain;
impl client::Blockchain for Blockchain {
type Error = ::std::io::Error;
fn latest_hash(&self) -> Result<block::HeaderHash, Self::Error> {
Ok(0.into())
}
fn header(&self, hash: &block::HeaderHash) -> Result<Option<block::Header>, Self::Error> {
Ok(if hash != &0.into() {
None
} else {
Some(block::Header {
number: 0,
parent_hash: 0.into(),
state_root: 0.into(),
timestamp: 0,
})
})
}
}