diff --git a/Cargo.lock b/Cargo.lock
index 21f5b45cea..5ce4568a10 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -419,6 +419,7 @@ version = "0.1.0"
dependencies = [
"codechain-core 0.1.0",
"codechain-key 0.1.0",
+ "codechain-keystore 0.1.0",
"codechain-logger 0.1.0",
"codechain-network 0.1.0",
"codechain-state 0.1.0",
diff --git a/keystore/src/error.rs b/keystore/src/error.rs
index b1d5b4cb31..b9782e945e 100644
--- a/keystore/src/error.rs
+++ b/keystore/src/error.rs
@@ -37,6 +37,8 @@ pub enum Error {
InvalidKeyFile(String),
/// Account creation failed.
CreationFailed,
+ /// Account already exists.
+ AlreadyExists,
/// `ckeys` error
CKey(CKeyError),
/// `CCrypto` error
@@ -55,6 +57,7 @@ impl fmt::Display for Error {
Error::InvalidMessage => "Invalid message".into(),
Error::InvalidKeyFile(ref reason) => format!("Invalid key file: {}", reason),
Error::CreationFailed => "Account creation failed".into(),
+ Error::AlreadyExists => "Account already exists".into(),
Error::CKey(ref err) => err.to_string(),
Error::CCrypto(ref err) => err.to_string(),
Error::Custom(ref s) => s.clone(),
diff --git a/keystore/src/keystore.rs b/keystore/src/keystore.rs
index 2666d38674..96e0440de7 100644
--- a/keystore/src/keystore.rs
+++ b/keystore/src/keystore.rs
@@ -64,7 +64,11 @@ impl KeyStore {
impl SimpleSecretStore for KeyStore {
fn insert_account(&self, secret: Secret, password: &Password) -> Result
{
- self.store.insert_account(secret, password)
+ let keypair = KeyPair::from_private(secret.into()).map_err(|_| Error::CreationFailed)?;
+ match self.has_account(&keypair.address())? {
+ true => Err(Error::AlreadyExists),
+ false => self.store.insert_account(secret, password),
+ }
}
fn accounts(&self) -> Result, Error> {
@@ -345,10 +349,10 @@ impl SimpleSecretStore for KeyMultiStore {
}
fn has_account(&self, account: &Address) -> Result {
- let mut accounts = self.get_accounts(account)?.into_iter();
- match accounts.next() {
- Some(_) => Ok(true),
- None => Ok(false),
+ match self.get_accounts(account) {
+ Ok(_) => Ok(true),
+ Err(Error::InvalidAccount) => Ok(false),
+ Err(e) => Err(e),
}
}
diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml
index 60b7aec82e..e4b4510156 100644
--- a/rpc/Cargo.toml
+++ b/rpc/Cargo.toml
@@ -8,6 +8,7 @@ authors = ["CodeChain Team "]
[dependencies]
codechain-core = { path = "../core" }
codechain-key = { path = "../key" }
+codechain-keystore = { path = "../keystore" }
codechain-logger = { path = "../util/logger" }
codechain-network = { path = "../network" }
codechain-state = { path = "../state" }
diff --git a/rpc/src/lib.rs b/rpc/src/lib.rs
index 84f47de00d..5086edddee 100644
--- a/rpc/src/lib.rs
+++ b/rpc/src/lib.rs
@@ -18,6 +18,7 @@ extern crate codechain_core as ccore;
#[macro_use]
extern crate codechain_logger as clogger;
extern crate codechain_key as ckey;
+extern crate codechain_keystore as ckeystore;
extern crate codechain_network as cnetwork;
extern crate codechain_state as cstate;
extern crate codechain_types as ctypes;
diff --git a/rpc/src/v1/errors.rs b/rpc/src/v1/errors.rs
index f27d4bf0f9..33b79ed32e 100644
--- a/rpc/src/v1/errors.rs
+++ b/rpc/src/v1/errors.rs
@@ -19,6 +19,7 @@ use std::fmt;
use ccore::AccountProviderError;
use ccore::Error as CoreError;
use ckey::Error as KeyError;
+use ckeystore::Error as KeystoreError;
use cnetwork::control::Error as NetworkControlError;
use cstate::StateError;
use ctypes::parcel::Error as ParcelError;
@@ -43,6 +44,11 @@ mod codes {
pub const TOO_LOW_FEE: i64 = -32033;
pub const TOO_CHEAP_TO_REPLACE: i64 = -32034;
pub const INVALID_NONCE: i64 = -32035;
+ pub const KEYSTORE_ERROR: i64 = -32040;
+ pub const KEY_ERROR: i64 = -32041;
+ pub const ALREADY_EXISTS: i64 = -32042;
+ pub const WRONG_PASSWORD: i64 = -32043;
+ pub const NO_SUCH_ACCOUNT: i64 = -32044;
pub const UNKNOWN_ERROR: i64 = -32099;
}
@@ -148,10 +154,39 @@ pub fn rlp(error: DecoderError) -> Error {
}
pub fn account_provider(error: AccountProviderError) -> Error {
- Error {
- code: ErrorCode::ServerError(codes::ACCOUNT_PROVIDER_ERROR),
- message: "AccountProvider error".into(),
- data: Some(Value::String(format!("{:?}", error))),
+ match error {
+ AccountProviderError::KeystoreError(error) => match error {
+ KeystoreError::InvalidAccount => Error {
+ code: ErrorCode::ServerError(codes::NO_SUCH_ACCOUNT),
+ message: "No Such Account".into(),
+ data: Some(Value::String(format!("{:?}", error))),
+ },
+ KeystoreError::InvalidPassword => Error {
+ code: ErrorCode::ServerError(codes::WRONG_PASSWORD),
+ message: "Wrong Password".into(),
+ data: Some(Value::String(format!("{:?}", error))),
+ },
+ KeystoreError::AlreadyExists => Error {
+ code: ErrorCode::ServerError(codes::ALREADY_EXISTS),
+ message: "Already Exists".into(),
+ data: Some(Value::String(format!("{:?}", error))),
+ },
+ _ => Error {
+ code: ErrorCode::ServerError(codes::KEYSTORE_ERROR),
+ message: "Keystore Error".into(),
+ data: Some(Value::String(format!("{:?}", error))),
+ },
+ },
+ AccountProviderError::KeyError(_) => Error {
+ code: ErrorCode::ServerError(codes::KEY_ERROR),
+ message: "Key Error".into(),
+ data: Some(Value::String(format!("{:?}", error))),
+ },
+ _ => Error {
+ code: ErrorCode::ServerError(codes::ACCOUNT_PROVIDER_ERROR),
+ message: "AccountProvider Error".into(),
+ data: Some(Value::String(format!("{:?}", error))),
+ },
}
}