Implementing RPC

This commit is contained in:
Tomasz Drwięga 2016-11-30 17:05:31 +01:00
parent 1d76bb7048
commit dcb7e1e638
4 changed files with 31 additions and 11 deletions

View File

@ -19,7 +19,7 @@ extern crate ethstore;
mod util; mod util;
use ethstore::{SecretStore, EthStore, SimpleSecretStore}; use ethstore::{EthStore, SimpleSecretStore};
use ethstore::ethkey::{Random, Generator, Secret, KeyPair, verify_address}; use ethstore::ethkey::{Random, Generator, Secret, KeyPair, verify_address};
use ethstore::dir::DiskDirectory; use ethstore::dir::DiskDirectory;
use util::TransientDir; use util::TransientDir;

View File

@ -15,6 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::fmt::Debug; use std::fmt::Debug;
use std::ops::Deref;
use rlp; use rlp;
use util::{Address, H256, U256, Uint, Bytes}; use util::{Address, H256, U256, Uint, Bytes};
use util::bytes::ToPretty; use util::bytes::ToPretty;
@ -53,6 +54,17 @@ pub enum WithToken<T: Debug> {
Yes(T, AccountToken), Yes(T, AccountToken),
} }
impl<T: Debug> Deref for WithToken<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
match *self {
WithToken::No(ref v) => v,
WithToken::Yes(ref v, _) => v,
}
}
}
impl<T: Debug> WithToken<T> { impl<T: Debug> WithToken<T> {
pub fn map<S, F>(self, f: F) -> WithToken<S> where pub fn map<S, F>(self, f: F) -> WithToken<S> where
S: Debug, S: Debug,
@ -67,7 +79,7 @@ impl<T: Debug> WithToken<T> {
pub fn into_value(self) -> T { pub fn into_value(self) -> T {
match self { match self {
WithToken::No(v) => v, WithToken::No(v) => v,
WithToken::Yes(v, ..) => v, WithToken::Yes(v, _) => v,
} }
} }
} }

View File

@ -28,7 +28,7 @@ use jsonrpc_core::Error;
use v1::traits::Signer; use v1::traits::Signer;
use v1::types::{TransactionModification, ConfirmationRequest, ConfirmationResponse, ConfirmationResponseWithToken, U256, Bytes}; use v1::types::{TransactionModification, ConfirmationRequest, ConfirmationResponse, ConfirmationResponseWithToken, U256, Bytes};
use v1::helpers::{errors, SignerService, SigningQueue, ConfirmationPayload}; use v1::helpers::{errors, SignerService, SigningQueue, ConfirmationPayload};
use v1::helpers::dispatch::{self, dispatch_transaction}; use v1::helpers::dispatch::{self, dispatch_transaction, WithToken};
/// Transactions confirmation (personal) rpc implementation. /// Transactions confirmation (personal) rpc implementation.
pub struct SignerClient<C, M> where C: MiningBlockChainClient, M: MinerService { pub struct SignerClient<C, M> where C: MiningBlockChainClient, M: MinerService {
@ -61,8 +61,8 @@ impl<C: 'static, M: 'static> SignerClient<C, M> where C: MiningBlockChainClient,
Ok(()) Ok(())
} }
fn confirm_internal<F>(&self, id: U256, modification: TransactionModification, f: F) -> Result<ConfirmationResponse, Error> where fn confirm_internal<F>(&self, id: U256, modification: TransactionModification, f: F) -> Result<WithToken<ConfirmationResponse>, Error> where
F: FnOnce(&C, &M, &AccountProvider, ConfirmationPayload) -> Result<ConfirmationResponse, Error>, F: FnOnce(&C, &M, &AccountProvider, ConfirmationPayload) -> Result<WithToken<ConfirmationResponse>, Error>,
{ {
try!(self.active()); try!(self.active());
@ -84,7 +84,7 @@ impl<C: 'static, M: 'static> SignerClient<C, M> where C: MiningBlockChainClient,
let result = f(&*client, &*miner, &*accounts, payload); let result = f(&*client, &*miner, &*accounts, payload);
// Execute // Execute
if let Ok(ref response) = result { if let Ok(ref response) = result {
signer.request_confirmed(id, Ok(response.clone())); signer.request_confirmed(id, Ok((*response).clone()));
} }
result result
}).unwrap_or_else(|| Err(errors::invalid_params("Unknown RequestID", id))) }).unwrap_or_else(|| Err(errors::invalid_params("Unknown RequestID", id)))
@ -109,12 +109,19 @@ impl<C: 'static, M: 'static> Signer for SignerClient<C, M> where C: MiningBlockC
fn confirm_request(&self, id: U256, modification: TransactionModification, pass: String) -> Result<ConfirmationResponse, Error> { fn confirm_request(&self, id: U256, modification: TransactionModification, pass: String) -> Result<ConfirmationResponse, Error> {
self.confirm_internal(id, modification, move |client, miner, accounts, payload| { self.confirm_internal(id, modification, move |client, miner, accounts, payload| {
dispatch::execute(client, miner, accounts, payload, dispatch::SignWith::Password(pass)) dispatch::execute(client, miner, accounts, payload, dispatch::SignWith::Password(pass))
.map(|v| v.into_value()) }).map(|v| v.into_value())
})
} }
fn confirm_request_with_token(&self, id: U256, modification: TransactionModification, token: String) -> Result<ConfirmationResponseWithToken, Error> { fn confirm_request_with_token(&self, id: U256, modification: TransactionModification, token: String) -> Result<ConfirmationResponseWithToken, Error> {
unimplemented!() self.confirm_internal(id, modification, move |client, miner, accounts, payload| {
dispatch::execute(client, miner, accounts, payload, dispatch::SignWith::Token(token))
}).and_then(|v| match v {
WithToken::No(_) => Err(errors::internal("Unexpected response without token.", "")),
WithToken::Yes(response, token) => Ok(ConfirmationResponseWithToken {
result: response,
token: token,
}),
})
} }
fn confirm_request_raw(&self, id: U256, bytes: Bytes) -> Result<ConfirmationResponse, Error> { fn confirm_request_raw(&self, id: U256, bytes: Bytes) -> Result<ConfirmationResponse, Error> {

View File

@ -247,10 +247,11 @@ fn should_confirm_transaction_with_token() {
}"#; }"#;
let response = r#"{"jsonrpc":"2.0","result":{"result":""#.to_owned() + let response = r#"{"jsonrpc":"2.0","result":{"result":""#.to_owned() +
format!("0x{:?}", t.hash()).as_ref() + format!("0x{:?}", t.hash()).as_ref() +
r#""token":""},"id":1}"#; r#"","token":""#;
// then // then
assert_eq!(tester.io.handle_request_sync(&request), Some(response.to_owned())); let result = tester.io.handle_request_sync(&request).unwrap();
assert!(result.starts_with(&response), "Should return correct result. Expected: {:?}, Got: {:?}", response, result);
assert_eq!(tester.signer.requests().len(), 0); assert_eq!(tester.signer.requests().len(), 0);
assert_eq!(tester.miner.imported_transactions.lock().len(), 1); assert_eq!(tester.miner.imported_transactions.lock().len(), 1);
} }