Splitting methods requiring signing into separate trait

This commit is contained in:
Tomasz Drwięga 2016-05-27 20:18:37 +02:00
parent 20846c11c9
commit 129ad0bbcb
9 changed files with 75 additions and 26 deletions

View File

@ -99,6 +99,7 @@ pub fn setup_dapps_server(
server.add_delegate(Web3Client::new().to_delegate()); server.add_delegate(Web3Client::new().to_delegate());
server.add_delegate(NetClient::new(&deps.sync).to_delegate()); server.add_delegate(NetClient::new(&deps.sync).to_delegate());
server.add_delegate(EthClient::new(&deps.client, &deps.sync, &deps.secret_store, &deps.miner, &deps.external_miner).to_delegate()); server.add_delegate(EthClient::new(&deps.client, &deps.sync, &deps.secret_store, &deps.miner, &deps.external_miner).to_delegate());
server.add_delegate(EthSigningUnsafeClient::new(&deps.client, &deps.secret_store, &deps.miner).to_delegate());
server.add_delegate(EthFilterClient::new(&deps.client, &deps.miner).to_delegate()); server.add_delegate(EthFilterClient::new(&deps.client, &deps.miner).to_delegate());
server.add_delegate(PersonalClient::new(&deps.secret_store, &deps.client, &deps.miner).to_delegate()); server.add_delegate(PersonalClient::new(&deps.secret_store, &deps.client, &deps.miner).to_delegate());
server.add_delegate(EthcoreClient::new(&deps.miner, deps.logger.clone(), deps.settings.clone()).to_delegate()); server.add_delegate(EthcoreClient::new(&deps.miner, deps.logger.clone(), deps.settings.clone()).to_delegate());

View File

@ -103,6 +103,7 @@ fn setup_rpc_server(apis: Vec<&str>, deps: &Arc<Dependencies>) -> Server {
modules.insert("eth".to_owned(), "1.0".to_owned()); modules.insert("eth".to_owned(), "1.0".to_owned());
server.add_delegate(EthClient::new(&deps.client, &deps.sync, &deps.secret_store, &deps.miner, &deps.external_miner).to_delegate()); server.add_delegate(EthClient::new(&deps.client, &deps.sync, &deps.secret_store, &deps.miner, &deps.external_miner).to_delegate());
server.add_delegate(EthFilterClient::new(&deps.client, &deps.miner).to_delegate()); server.add_delegate(EthFilterClient::new(&deps.client, &deps.miner).to_delegate());
server.add_delegate(EthSigningUnsafeClient::new(&deps.client, &deps.secret_store, &deps.miner).to_delegate());
}, },
"personal" => { "personal" => {
modules.insert("personal".to_owned(), "1.0".to_owned()); modules.insert("personal".to_owned(), "1.0".to_owned());

View File

@ -63,8 +63,9 @@ fn do_start(conf: Configuration, deps: Dependencies) -> SignerServer {
server.add_delegate(Web3Client::new().to_delegate()); server.add_delegate(Web3Client::new().to_delegate());
server.add_delegate(NetClient::new(&deps.sync).to_delegate()); server.add_delegate(NetClient::new(&deps.sync).to_delegate());
server.add_delegate(EthClient::new(&deps.client, &deps.sync, &deps.secret_store, &deps.miner, &deps.external_miner).to_delegate()); server.add_delegate(EthClient::new(&deps.client, &deps.sync, &deps.secret_store, &deps.miner, &deps.external_miner).to_delegate());
server.add_delegate(EthSigningUnsafeClient::new(&deps.client, &deps.secret_store, &deps.miner).to_delegate());
server.add_delegate(EthFilterClient::new(&deps.client, &deps.miner).to_delegate()); server.add_delegate(EthFilterClient::new(&deps.client, &deps.miner).to_delegate());
server.add_delegate(PersonalClient::new(&deps.secret_store).to_delegate()); server.add_delegate(PersonalClient::new(&deps.secret_store, &deps.client, &deps.miner).to_delegate());
server.start(addr) server.start(addr)
}; };

View File

@ -35,7 +35,7 @@ use ethcore::transaction::{Transaction as EthTransaction, SignedTransaction, Act
use ethcore::log_entry::LogEntry; use ethcore::log_entry::LogEntry;
use ethcore::filter::Filter as EthcoreFilter; use ethcore::filter::Filter as EthcoreFilter;
use self::ethash::SeedHashCompute; use self::ethash::SeedHashCompute;
use v1::traits::{Eth, EthFilter}; use v1::traits::{Eth, EthFilter, EthSigning};
use v1::types::{Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, Transaction, TransactionRequest, CallRequest, OptionalValue, Index, Filter, Log, Receipt}; use v1::types::{Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, Transaction, TransactionRequest, CallRequest, OptionalValue, Index, Filter, Log, Receipt};
use v1::helpers::{PollFilter, PollManager}; use v1::helpers::{PollFilter, PollManager};
use v1::impls::{dispatch_transaction, sign_and_dispatch}; use v1::impls::{dispatch_transaction, sign_and_dispatch};
@ -494,17 +494,6 @@ impl<C, S, A, M, EM> Eth for EthClient<C, S, A, M, EM> where
}) })
} }
fn send_transaction(&self, params: Params) -> Result<Value, Error> {
from_params::<(TransactionRequest, )>(params)
.and_then(|(request, )| {
let accounts = take_weak!(self.accounts);
match accounts.account_secret(&request.from) {
Ok(secret) => sign_and_dispatch(&self.client, &self.miner, request, secret),
Err(_) => to_value(&H256::zero())
}
})
}
fn send_raw_transaction(&self, params: Params) -> Result<Value, Error> { fn send_raw_transaction(&self, params: Params) -> Result<Value, Error> {
from_params::<(Bytes, )>(params) from_params::<(Bytes, )>(params)
.and_then(|(raw_transaction, )| { .and_then(|(raw_transaction, )| {
@ -726,3 +715,48 @@ impl<C, M> EthFilter for EthFilterClient<C, M> where
}) })
} }
} }
/// Implementation of functions that require signing when no trusted signer is used.
pub struct EthSigningUnsafeClient<C, A, M> where
C: BlockChainClient,
A: AccountProvider,
M: MinerService {
client: Weak<C>,
accounts: Weak<A>,
miner: Weak<M>,
}
impl<C, A, M> EthSigningUnsafeClient<C, A, M> where
C: BlockChainClient,
A: AccountProvider,
M: MinerService {
/// Creates new EthClient.
pub fn new(client: &Arc<C>, accounts: &Arc<A>, miner: &Arc<M>)
-> Self {
EthSigningUnsafeClient {
client: Arc::downgrade(client),
miner: Arc::downgrade(miner),
accounts: Arc::downgrade(accounts),
}
}
}
impl<C, A, M> EthSigning for EthSigningUnsafeClient<C, A, M> where
C: BlockChainClient + 'static,
A: AccountProvider + 'static,
M: MinerService + 'static {
fn send_transaction(&self, params: Params) -> Result<Value, Error> {
from_params::<(TransactionRequest, )>(params)
.and_then(|(request, )| {
let accounts = take_weak!(self.accounts);
match accounts.account_secret(&request.from) {
Ok(secret) => sign_and_dispatch(&self.client, &self.miner, request, secret),
Err(_) => to_value(&H256::zero())
}
})
}
}

View File

@ -34,7 +34,7 @@ mod traces;
mod rpc; mod rpc;
pub use self::web3::Web3Client; pub use self::web3::Web3Client;
pub use self::eth::{EthClient, EthFilterClient}; pub use self::eth::{EthClient, EthFilterClient, EthSigningUnsafeClient};
pub use self::net::NetClient; pub use self::net::NetClient;
pub use self::personal::PersonalClient; pub use self::personal::PersonalClient;
pub use self::ethcore::EthcoreClient; pub use self::ethcore::EthcoreClient;

View File

@ -25,5 +25,5 @@ pub mod traits;
pub mod tests; pub mod tests;
pub mod types; pub mod types;
pub use self::traits::{Web3, Eth, EthFilter, Personal, Net, Ethcore, Traces, Rpc}; pub use self::traits::{Web3, Eth, EthFilter, EthSigning, Personal, Net, Ethcore, Traces, Rpc};
pub use self::impls::*; pub use self::impls::*;

View File

@ -26,7 +26,7 @@ use ethcore::log_entry::{LocalizedLogEntry, LogEntry};
use ethcore::receipt::LocalizedReceipt; use ethcore::receipt::LocalizedReceipt;
use ethcore::transaction::{Transaction, Action}; use ethcore::transaction::{Transaction, Action};
use ethminer::ExternalMiner; use ethminer::ExternalMiner;
use v1::{Eth, EthClient}; use v1::{Eth, EthClient, EthSigning, EthSigningUnsafeClient};
use v1::tests::helpers::{TestSyncProvider, Config, TestMinerService}; use v1::tests::helpers::{TestSyncProvider, Config, TestMinerService};
fn blockchain_client() -> Arc<TestBlockChainClient> { fn blockchain_client() -> Arc<TestBlockChainClient> {
@ -70,8 +70,11 @@ impl Default for EthTester {
let hashrates = Arc::new(RwLock::new(HashMap::new())); let hashrates = Arc::new(RwLock::new(HashMap::new()));
let external_miner = Arc::new(ExternalMiner::new(hashrates.clone())); let external_miner = Arc::new(ExternalMiner::new(hashrates.clone()));
let eth = EthClient::new(&client, &sync, &ap, &miner, &external_miner).to_delegate(); let eth = EthClient::new(&client, &sync, &ap, &miner, &external_miner).to_delegate();
let sign = EthSigningUnsafeClient::new(&client, &ap, &miner).to_delegate();
let io = IoHandler::new(); let io = IoHandler::new();
io.add_delegate(eth); io.add_delegate(eth);
io.add_delegate(sign);
EthTester { EthTester {
client: client, client: client,
sync: sync, sync: sync,

View File

@ -74,12 +74,6 @@ pub trait Eth: Sized + Send + Sync + 'static {
/// Returns the code at given address at given time (block number). /// Returns the code at given address at given time (block number).
fn code_at(&self, _: Params) -> Result<Value, Error> { rpc_unimplemented!() } fn code_at(&self, _: Params) -> Result<Value, Error> { rpc_unimplemented!() }
/// Signs the data with given address signature.
fn sign(&self, _: Params) -> Result<Value, Error> { rpc_unimplemented!() }
/// Sends transaction.
fn send_transaction(&self, _: Params) -> Result<Value, Error> { rpc_unimplemented!() }
/// Sends signed transaction. /// Sends signed transaction.
fn send_raw_transaction(&self, _: Params) -> Result<Value, Error> { rpc_unimplemented!() } fn send_raw_transaction(&self, _: Params) -> Result<Value, Error> { rpc_unimplemented!() }
@ -150,8 +144,6 @@ pub trait Eth: Sized + Send + Sync + 'static {
delegate.add_method("eth_getUncleCountByBlockHash", Eth::block_uncles_count_by_hash); delegate.add_method("eth_getUncleCountByBlockHash", Eth::block_uncles_count_by_hash);
delegate.add_method("eth_getUncleCountByBlockNumber", Eth::block_uncles_count_by_number); delegate.add_method("eth_getUncleCountByBlockNumber", Eth::block_uncles_count_by_number);
delegate.add_method("eth_getCode", Eth::code_at); delegate.add_method("eth_getCode", Eth::code_at);
delegate.add_method("eth_sign", Eth::sign);
delegate.add_method("eth_sendTransaction", Eth::send_transaction);
delegate.add_method("eth_sendRawTransaction", Eth::send_raw_transaction); delegate.add_method("eth_sendRawTransaction", Eth::send_raw_transaction);
delegate.add_method("eth_call", Eth::call); delegate.add_method("eth_call", Eth::call);
delegate.add_method("eth_estimateGas", Eth::estimate_gas); delegate.add_method("eth_estimateGas", Eth::estimate_gas);
@ -208,3 +200,20 @@ pub trait EthFilter: Sized + Send + Sync + 'static {
delegate delegate
} }
} }
/// Signing methods implementation relying on unlocked accounts.
pub trait EthSigning: Sized + Send + Sync + 'static {
/// Signs the data with given address signature.
fn sign(&self, _: Params) -> Result<Value, Error> { rpc_unimplemented!() }
/// Sends transaction.
fn send_transaction(&self, _: Params) -> Result<Value, Error> { rpc_unimplemented!() }
/// Should be used to convert object to io delegate.
fn to_delegate(self) -> IoDelegate<Self> {
let mut delegate = IoDelegate::new(Arc::new(self));
delegate.add_method("eth_sign", EthSigning::sign);
delegate.add_method("eth_sendTransaction", EthSigning::send_transaction);
delegate
}
}

View File

@ -29,7 +29,7 @@ pub mod traces;
pub mod rpc; pub mod rpc;
pub use self::web3::Web3; pub use self::web3::Web3;
pub use self::eth::{Eth, EthFilter}; pub use self::eth::{Eth, EthFilter, EthSigning};
pub use self::net::Net; pub use self::net::Net;
pub use self::personal::Personal; pub use self::personal::Personal;
pub use self::ethcore::Ethcore; pub use self::ethcore::Ethcore;