traitified secret store
This commit is contained in:
parent
094ae4e9f9
commit
5571503c22
@ -30,20 +30,23 @@ use ethcore::ethereum::denominations::shannon;
|
|||||||
use v1::traits::{Eth, EthFilter};
|
use v1::traits::{Eth, EthFilter};
|
||||||
use v1::types::{Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, Transaction, TransactionRequest, OptionalValue, Index, Filter, Log};
|
use v1::types::{Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, Transaction, TransactionRequest, OptionalValue, Index, Filter, Log};
|
||||||
use v1::helpers::{PollFilter, PollManager};
|
use v1::helpers::{PollFilter, PollManager};
|
||||||
|
use util::keys::store::AccountProvider;
|
||||||
|
|
||||||
/// Eth rpc implementation.
|
/// Eth rpc implementation.
|
||||||
pub struct EthClient<C, S> where C: BlockChainClient, S: SyncStatusProvider {
|
pub struct EthClient<C, S, A> where C: BlockChainClient, S: SyncStatusProvider, A: AccountProvider {
|
||||||
client: Weak<C>,
|
client: Weak<C>,
|
||||||
sync: Weak<S>,
|
sync: Weak<S>,
|
||||||
|
accounts: Weak<A>,
|
||||||
hashrates: RwLock<HashMap<H256, u64>>,
|
hashrates: RwLock<HashMap<H256, u64>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, S> EthClient<C, S> where C: BlockChainClient, S: SyncStatusProvider {
|
impl<C, S, A> EthClient<C, S, A> where C: BlockChainClient, S: SyncStatusProvider, A: AccountProvider {
|
||||||
/// Creates new EthClient.
|
/// Creates new EthClient.
|
||||||
pub fn new(client: &Arc<C>, sync: &Arc<S>) -> Self {
|
pub fn new(client: &Arc<C>, sync: &Arc<S>, accounts: &Arc<A>) -> Self {
|
||||||
EthClient {
|
EthClient {
|
||||||
client: Arc::downgrade(client),
|
client: Arc::downgrade(client),
|
||||||
sync: Arc::downgrade(sync),
|
sync: Arc::downgrade(sync),
|
||||||
|
accounts: Arc::downgrade(accounts),
|
||||||
hashrates: RwLock::new(HashMap::new()),
|
hashrates: RwLock::new(HashMap::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,7 +97,7 @@ impl<C, S> EthClient<C, S> where C: BlockChainClient, S: SyncStatusProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, S> Eth for EthClient<C, S> where C: BlockChainClient + 'static, S: SyncStatusProvider + 'static {
|
impl<C, S, A> Eth for EthClient<C, S, A> where C: BlockChainClient + 'static, S: SyncStatusProvider + 'static, A: AccountProvider + 'static {
|
||||||
fn protocol_version(&self, params: Params) -> Result<Value, Error> {
|
fn protocol_version(&self, params: Params) -> Result<Value, Error> {
|
||||||
match params {
|
match params {
|
||||||
Params::None => to_value(&U256::from(take_weak!(self.sync).status().protocol_version)),
|
Params::None => to_value(&U256::from(take_weak!(self.sync).status().protocol_version)),
|
||||||
@ -256,9 +259,8 @@ impl<C, S> Eth for EthClient<C, S> where C: BlockChainClient + 'static, S: SyncS
|
|||||||
fn send_transaction(&self, params: Params) -> Result<Value, Error> {
|
fn send_transaction(&self, params: Params) -> Result<Value, Error> {
|
||||||
from_params::<(TransactionRequest, )>(params)
|
from_params::<(TransactionRequest, )>(params)
|
||||||
.and_then(|(transaction_request, )| {
|
.and_then(|(transaction_request, )| {
|
||||||
let client = take_weak!(self.client);
|
let accounts = take_weak!(self.accounts);
|
||||||
let store = client.secret_store().read().unwrap();
|
match accounts.account_secret(&transaction_request.from) {
|
||||||
match store.account_secret(&transaction_request.from) {
|
|
||||||
Ok(secret) => {
|
Ok(secret) => {
|
||||||
let sync = take_weak!(self.sync);
|
let sync = take_weak!(self.sync);
|
||||||
let (transaction, _) = transaction_request.to_eth();
|
let (transaction, _) = transaction_request.to_eth();
|
||||||
|
@ -78,6 +78,18 @@ struct AccountUnlock {
|
|||||||
expires: DateTime<UTC>,
|
expires: DateTime<UTC>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Basic account management trait
|
||||||
|
pub trait AccountProvider : Send + Sync {
|
||||||
|
/// Unlocks account with the password provided
|
||||||
|
fn unlock_account(&self, account: &Address, pass: &str) -> Result<(), EncryptedHashMapError>;
|
||||||
|
/// Creates account
|
||||||
|
fn new_account(&mut self, pass: &str) -> Result<Address, ::std::io::Error>;
|
||||||
|
/// Returns secret for unlocked account
|
||||||
|
fn account_secret(&self, account: &Address) -> Result<crypto::Secret, SigningError>;
|
||||||
|
/// Returns secret for unlocked account
|
||||||
|
fn sign(&self, account: &Address, message: &H256) -> Result<crypto::Signature, SigningError>;
|
||||||
|
}
|
||||||
|
|
||||||
impl SecretStore {
|
impl SecretStore {
|
||||||
/// new instance of Secret Store in default home directory
|
/// new instance of Secret Store in default home directory
|
||||||
pub fn new() -> SecretStore {
|
pub fn new() -> SecretStore {
|
||||||
@ -144,9 +156,11 @@ impl SecretStore {
|
|||||||
unlocks: RwLock::new(HashMap::new()),
|
unlocks: RwLock::new(HashMap::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AccountProvider for SecretStore {
|
||||||
/// Unlocks account for use
|
/// Unlocks account for use
|
||||||
pub fn unlock_account(&self, account: &Address, pass: &str) -> Result<(), EncryptedHashMapError> {
|
fn unlock_account(&self, account: &Address, pass: &str) -> Result<(), EncryptedHashMapError> {
|
||||||
let secret_id = try!(self.account(&account).ok_or(EncryptedHashMapError::UnknownIdentifier));
|
let secret_id = try!(self.account(&account).ok_or(EncryptedHashMapError::UnknownIdentifier));
|
||||||
let secret = try!(self.get(&secret_id, pass));
|
let secret = try!(self.get(&secret_id, pass));
|
||||||
{
|
{
|
||||||
@ -160,7 +174,7 @@ impl SecretStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates new account
|
/// Creates new account
|
||||||
pub fn new_account(&mut self, pass: &str) -> Result<Address, ::std::io::Error> {
|
fn new_account(&mut self, pass: &str) -> Result<Address, ::std::io::Error> {
|
||||||
let secret = H256::random();
|
let secret = H256::random();
|
||||||
let key_id = H128::random();
|
let key_id = H128::random();
|
||||||
self.insert(key_id.clone(), secret, pass);
|
self.insert(key_id.clone(), secret, pass);
|
||||||
@ -173,7 +187,7 @@ impl SecretStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Signs message with unlocked account
|
/// Signs message with unlocked account
|
||||||
pub fn sign(&self, account: &Address, message: &H256) -> Result<crypto::Signature, SigningError> {
|
fn sign(&self, account: &Address, message: &H256) -> Result<crypto::Signature, SigningError> {
|
||||||
let read_lock = self.unlocks.read().unwrap();
|
let read_lock = self.unlocks.read().unwrap();
|
||||||
let unlock = try!(read_lock.get(account).ok_or(SigningError::AccountNotUnlocked));
|
let unlock = try!(read_lock.get(account).ok_or(SigningError::AccountNotUnlocked));
|
||||||
match crypto::KeyPair::from_secret(unlock.secret) {
|
match crypto::KeyPair::from_secret(unlock.secret) {
|
||||||
@ -186,7 +200,7 @@ impl SecretStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns secret for unlocked account
|
/// Returns secret for unlocked account
|
||||||
pub fn account_secret(&self, account: &Address) -> Result<crypto::Secret, SigningError> {
|
fn account_secret(&self, account: &Address) -> Result<crypto::Secret, SigningError> {
|
||||||
let read_lock = self.unlocks.read().unwrap();
|
let read_lock = self.unlocks.read().unwrap();
|
||||||
let unlock = try!(read_lock.get(account).ok_or(SigningError::AccountNotUnlocked));
|
let unlock = try!(read_lock.get(account).ok_or(SigningError::AccountNotUnlocked));
|
||||||
Ok(unlock.secret as crypto::Secret)
|
Ok(unlock.secret as crypto::Secret)
|
||||||
|
Loading…
Reference in New Issue
Block a user