Create an account for chain=dev (#5612)

* implement From<&'static str> for Secret

* Dev account.

* Fix Secret semantics.
This commit is contained in:
Tomasz Drwięga 2017-05-19 17:06:36 +02:00 committed by Gav Wood
parent e7abd3510a
commit 3ff72794e5
27 changed files with 83 additions and 45 deletions

View File

@ -1564,7 +1564,7 @@ mod tests {
}
fn secret() -> Secret {
Secret::from_slice(&"".sha3()).unwrap()
"".sha3().into()
}
#[test]

View File

@ -463,7 +463,6 @@ mod tests {
use util::*;
use header::Header;
use error::{Error, BlockError};
use ethkey::Secret;
use rlp::encode;
use block::*;
use tests::helpers::*;
@ -513,8 +512,8 @@ mod tests {
#[test]
fn generates_seal_and_does_not_double_propose() {
let tap = Arc::new(AccountProvider::transient_provider());
let addr1 = tap.insert_account(Secret::from_slice(&"1".sha3()).unwrap(), "1").unwrap();
let addr2 = tap.insert_account(Secret::from_slice(&"2".sha3()).unwrap(), "2").unwrap();
let addr1 = tap.insert_account("1".sha3().into(), "1").unwrap();
let addr2 = tap.insert_account("2".sha3().into(), "2").unwrap();
let spec = Spec::new_test_round();
let engine = &*spec.engine;
@ -545,7 +544,7 @@ mod tests {
#[test]
fn proposer_switching() {
let tap = AccountProvider::transient_provider();
let addr = tap.insert_account(Secret::from_slice(&"0".sha3()).unwrap(), "0").unwrap();
let addr = tap.insert_account("0".sha3().into(), "0").unwrap();
let mut parent_header: Header = Header::default();
parent_header.set_seal(vec![encode(&0usize).to_vec()]);
parent_header.set_gas_limit(U256::from_str("222222").unwrap());
@ -570,7 +569,7 @@ mod tests {
#[test]
fn rejects_future_block() {
let tap = AccountProvider::transient_provider();
let addr = tap.insert_account(Secret::from_slice(&"0".sha3()).unwrap(), "0").unwrap();
let addr = tap.insert_account("0".sha3().into(), "0").unwrap();
let mut parent_header: Header = Header::default();
parent_header.set_seal(vec![encode(&0usize).to_vec()]);
@ -596,7 +595,7 @@ mod tests {
#[test]
fn rejects_step_backwards() {
let tap = AccountProvider::transient_provider();
let addr = tap.insert_account(Secret::from_slice(&"0".sha3()).unwrap(), "0").unwrap();
let addr = tap.insert_account("0".sha3().into(), "0").unwrap();
let mut parent_header: Header = Header::default();
parent_header.set_seal(vec![encode(&4usize).to_vec()]);

View File

@ -229,7 +229,6 @@ mod tests {
use error::{BlockError, Error};
use tests::helpers::*;
use account_provider::AccountProvider;
use ethkey::Secret;
use header::Header;
use spec::Spec;
use engines::Seal;
@ -281,7 +280,7 @@ mod tests {
#[test]
fn can_generate_seal() {
let tap = AccountProvider::transient_provider();
let addr = tap.insert_account(Secret::from_slice(&"".sha3()).unwrap(), "").unwrap();
let addr = tap.insert_account("".sha3().into(), "").unwrap();
let spec = new_test_authority();
let engine = &*spec.engine;
@ -299,7 +298,7 @@ mod tests {
#[test]
fn seals_internally() {
let tap = AccountProvider::transient_provider();
let authority = tap.insert_account(Secret::from_slice(&"".sha3()).unwrap(), "").unwrap();
let authority = tap.insert_account("".sha3().into(), "").unwrap();
let engine = new_test_authority().engine;
assert!(!engine.seals_internally().unwrap());

View File

@ -200,7 +200,6 @@ pub fn message_hash(vote_step: VoteStep, block_hash: H256) -> H256 {
mod tests {
use util::*;
use rlp::*;
use ethkey::Secret;
use account_provider::AccountProvider;
use header::Header;
use super::super::Step;
@ -250,7 +249,7 @@ mod tests {
#[test]
fn generate_and_verify() {
let tap = Arc::new(AccountProvider::transient_provider());
let addr = tap.insert_account(Secret::from_slice(&"0".sha3()).unwrap(), "0").unwrap();
let addr = tap.insert_account("0".sha3().into(), "0").unwrap();
tap.unlock_account_permanently(addr, "0".into()).unwrap();
let mi = message_info_rlp(&VoteStep::new(123, 2, Step::Precommit), Some(H256::default()));

View File

@ -659,7 +659,6 @@ mod tests {
use block::*;
use error::{Error, BlockError};
use header::Header;
use ethkey::Secret;
use client::chain_notify::ChainNotify;
use miner::MinerService;
use tests::helpers::*;
@ -708,7 +707,7 @@ mod tests {
}
fn insert_and_unlock(tap: &Arc<AccountProvider>, acc: &str) -> Address {
let addr = tap.insert_account(Secret::from_slice(&acc.sha3()).unwrap(), acc).unwrap();
let addr = tap.insert_account(acc.sha3().into(), acc).unwrap();
tap.unlock_account_permanently(addr, acc.into()).unwrap();
addr
}

View File

@ -116,7 +116,6 @@ impl ValidatorSet for ValidatorContract {
mod tests {
use util::*;
use rlp::encode;
use ethkey::Secret;
use spec::Spec;
use header::Header;
use account_provider::AccountProvider;
@ -140,7 +139,7 @@ mod tests {
#[test]
fn reports_validators() {
let tap = Arc::new(AccountProvider::transient_provider());
let v1 = tap.insert_account(Secret::from_slice(&"1".sha3()).unwrap(), "").unwrap();
let v1 = tap.insert_account("1".sha3().into(), "").unwrap();
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_contract, Some(tap.clone()));
client.engine().register_client(Arc::downgrade(&client));
let validator_contract = Address::from_str("0000000000000000000000000000000000000005").unwrap();

View File

@ -166,9 +166,9 @@ mod tests {
fn uses_current_set() {
::env_logger::init().unwrap();
let tap = Arc::new(AccountProvider::transient_provider());
let s0 = Secret::from_slice(&"0".sha3()).unwrap();
let s0: Secret = "0".sha3().into();
let v0 = tap.insert_account(s0.clone(), "").unwrap();
let v1 = tap.insert_account(Secret::from_slice(&"1".sha3()).unwrap(), "").unwrap();
let v1 = tap.insert_account("1".sha3().into(), "").unwrap();
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_multi, Some(tap));
client.engine().register_client(Arc::downgrade(&client));

View File

@ -294,9 +294,9 @@ mod tests {
#[test]
fn knows_validators() {
let tap = Arc::new(AccountProvider::transient_provider());
let s0 = Secret::from_slice(&"1".sha3()).unwrap();
let s0: Secret = "1".sha3().into();
let v0 = tap.insert_account(s0.clone(), "").unwrap();
let v1 = tap.insert_account(Secret::from_slice(&"0".sha3()).unwrap(), "").unwrap();
let v1 = tap.insert_account("0".sha3().into(), "").unwrap();
let network_id = Spec::new_validator_safe_contract().network_id();
let client = generate_dummy_client_with_spec_and_accounts(Spec::new_validator_safe_contract, Some(tap));
client.engine().register_client(Arc::downgrade(&client));

View File

@ -962,7 +962,7 @@ mod tests {
use types::executed::CallType;
fn secret() -> Secret {
Secret::from_slice(&"".sha3()).unwrap()
"".sha3().into()
}
#[test]

View File

@ -27,7 +27,7 @@ use devtools::*;
use miner::Miner;
use spec::Spec;
use views::BlockView;
use ethkey::{KeyPair, Secret};
use ethkey::KeyPair;
use transaction::{PendingTransaction, Transaction, Action, Condition};
use miner::MinerService;
@ -296,7 +296,7 @@ fn change_history_size() {
#[test]
fn does_not_propagate_delayed_transactions() {
let key = KeyPair::from_secret(Secret::from_slice(&"test".sha3()).unwrap()).unwrap();
let key = KeyPair::from_secret("test".sha3().into()).unwrap();
let secret = key.secret();
let tx0 = PendingTransaction::new(Transaction {
nonce: 0.into(),

View File

@ -113,7 +113,7 @@ impl HeapSizeOf for Transaction {
impl From<ethjson::state::Transaction> for SignedTransaction {
fn from(t: ethjson::state::Transaction) -> Self {
let to: Option<ethjson::hash::Address> = t.to.into();
let secret = t.secret.map(|s| Secret::from_slice(&s.0).expect("Valid secret expected."));
let secret = t.secret.map(|s| Secret::from_slice(&s.0));
let tx = Transaction {
nonce: t.nonce.into(),
gas_price: t.gas_price.into(),

View File

@ -192,7 +192,7 @@ pub mod ecdh {
let sec = key::SecretKey::from_slice(context, &secret)?;
let shared = ecdh::SharedSecret::new_raw(context, &publ, &sec);
Secret::from_slice(&shared[0..32])
Secret::from_unsafe_slice(&shared[0..32])
.map_err(|_| Error::Secp(SecpError::InvalidSecretKey))
}
}

View File

@ -38,7 +38,7 @@ impl Generator for Brain {
match i > 16384 {
false => i += 1,
true => {
if let Ok(secret) = Secret::from_slice(&secret) {
if let Ok(secret) = Secret::from_unsafe_slice(&secret) {
let result = KeyPair::from_secret(secret);
if result.as_ref().ok().map_or(false, |r| r.address()[0] == 0) {
return result;

View File

@ -99,8 +99,7 @@ impl ExtendedSecret {
pub fn derive<T>(&self, index: Derivation<T>) -> ExtendedSecret where T: Label {
let (derived_key, next_chain_code) = derivation::private(*self.secret, self.chain_code, index);
let derived_secret = Secret::from_slice(&*derived_key)
.expect("Derivation always produced a valid private key; qed");
let derived_secret = Secret::from_slice(&*derived_key);
ExtendedSecret::with_code(derived_secret, next_chain_code)
}
@ -181,7 +180,7 @@ impl ExtendedKeyPair {
pub fn with_seed(seed: &[u8]) -> Result<ExtendedKeyPair, DerivationError> {
let (master_key, chain_code) = derivation::seed_pair(seed);
Ok(ExtendedKeyPair::with_secret(
Secret::from_slice(&*master_key).map_err(|_| DerivationError::InvalidSeed)?,
Secret::from_unsafe_slice(&*master_key).map_err(|_| DerivationError::InvalidSeed)?,
chain_code,
))
}
@ -402,7 +401,7 @@ mod tests {
fn test_extended<F>(f: F, test_private: H256) where F: Fn(ExtendedSecret) -> ExtendedSecret {
let (private_seed, chain_code) = master_chain_basic();
let extended_secret = ExtendedSecret::with_code(Secret::from_slice(&*private_seed).unwrap(), chain_code);
let extended_secret = ExtendedSecret::with_code(Secret::from_slice(&*private_seed), chain_code);
let derived = f(extended_secret);
assert_eq!(**derived.as_raw(), test_private);
}

View File

@ -62,7 +62,7 @@ impl KeyPair {
}
pub fn from_secret_slice(slice: &[u8]) -> Result<KeyPair, Error> {
Self::from_secret(Secret::from_slice(slice)?)
Self::from_secret(Secret::from_unsafe_slice(slice)?)
}
pub fn from_keypair(sec: key::SecretKey, publ: key::PublicKey) -> Self {

View File

@ -33,7 +33,7 @@ impl fmt::Debug for Secret {
}
impl Secret {
fn from_slice_unchecked(key: &[u8]) -> Self {
pub fn from_slice(key: &[u8]) -> Self {
assert_eq!(32, key.len(), "Caller should provide 32-byte length slice");
let mut h = H256::default();
@ -41,11 +41,17 @@ impl Secret {
Secret { inner: h }
}
pub fn from_slice(key: &[u8]) -> Result<Self, Error> {
/// Imports and validates the key.
pub fn from_unsafe_slice(key: &[u8]) -> Result<Self, Error> {
let secret = key::SecretKey::from_slice(&super::SECP256K1, key)?;
Ok(secret.into())
}
/// Checks validity of this key.
pub fn check_validity(&self) -> Result<(), Error> {
self.to_secp256k1_secret().map(|_| ())
}
/// Inplace add one secret key to another (scalar + scalar)
pub fn add(&mut self, other: &Secret) -> Result<(), Error> {
let mut key_secret = self.to_secp256k1_secret()?;
@ -121,14 +127,25 @@ impl Secret {
impl FromStr for Secret {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let hash = H256::from_str(s).map_err(|e| Error::Custom(format!("{:?}", e)))?;
Self::from_slice(&hash)
Ok(H256::from_str(s).map_err(|e| Error::Custom(format!("{:?}", e)))?.into())
}
}
impl From<H256> for Secret {
fn from(s: H256) -> Self {
Secret::from_slice(&s)
}
}
impl From<&'static str> for Secret {
fn from(s: &'static str) -> Self {
s.parse().expect(&format!("invalid string literal for {}: '{}'", stringify!(Self), s))
}
}
impl From<key::SecretKey> for Secret {
fn from(key: key::SecretKey) -> Self {
Self::from_slice_unchecked(&key[0..32])
Self::from_slice(&key[0..32])
}
}

View File

@ -122,7 +122,7 @@ impl Crypto {
}
let secret = self.do_decrypt(password, 32)?;
Ok(Secret::from_slice(&secret)?)
Ok(Secret::from_unsafe_slice(&secret)?)
}
/// Try to decrypt and return result as is

View File

@ -50,7 +50,7 @@ impl PresaleWallet {
let len = crypto::aes::decrypt_cbc(&derived_key, &self.iv, &self.ciphertext, &mut key).map_err(|_| Error::InvalidPassword)?;
let unpadded = &key[..len];
let secret = Secret::from_slice(&unpadded.keccak256())?;
let secret = Secret::from_unsafe_slice(&unpadded.keccak256())?;
if let Ok(kp) = KeyPair::from_secret(secret) {
if kp.address() == self.address {
return Ok(kp)

View File

@ -695,7 +695,7 @@ impl Configuration {
ret.listen_address = listen.map(|l| format!("{}", l));
ret.public_address = public.map(|p| format!("{}", p));
ret.use_secret = match self.args.flag_node_key.as_ref()
.map(|s| s.parse::<Secret>().or_else(|_| Secret::from_slice(&s.sha3())).map_err(|e| format!("Invalid key: {:?}", e))
.map(|s| s.parse::<Secret>().or_else(|_| Secret::from_unsafe_slice(&s.sha3())).map_err(|e| format!("Invalid key: {:?}", e))
) {
None => None,
Some(Ok(key)) => Some(key),

View File

@ -30,6 +30,7 @@ use ethcore::account_provider::{AccountProvider, AccountProviderSettings};
use ethcore::miner::{Miner, MinerService, ExternalMiner, MinerOptions};
use ethcore::snapshot;
use ethcore::verification::queue::VerifierSettings;
use ethcore::ethstore::ethkey;
use light::Cache as LightDataCache;
use ethsync::SyncConfig;
use informant::Informant;
@ -820,9 +821,31 @@ fn prepare_account_provider(spec: &SpecType, dirs: &Directories, data_dir: &str,
}
}
// Add development account if running dev chain:
if let SpecType::Dev = *spec {
insert_dev_account(&account_provider);
}
Ok(account_provider)
}
fn insert_dev_account(account_provider: &AccountProvider) {
let secret: ethkey::Secret = "4d5db4107d237df6a3d58ee5f70ae63d73d7658d4026f2eefd2f204c81682cb7".into();
let dev_account = ethkey::KeyPair::from_secret(secret.clone()).expect("Valid secret produces valid key;qed");
if let Ok(false) = account_provider.has_account(dev_account.address()) {
match account_provider.insert_account(secret, "") {
Err(e) => warn!("Unable to add development account: {}", e),
Ok(address) => {
let _ = account_provider.set_account_name(address.clone(), "Development Account".into());
let _ = account_provider.set_account_meta(address, ::serde_json::to_string(&(vec![
("description", "Never use this account outside of develoopment chain!"),
("passwordHint","Password is empty string"),
].into_iter().collect::<::std::collections::HashMap<_,_>>())).expect("Serialization of hashmap does not fail."));
},
}
}
}
// Construct an error `String` with an adaptive hint on how to create an account.
fn build_create_account_hint(spec: &SpecType, keys: &str) -> String {
format!("You can create an account via RPC, UI or `parity account new --chain {} --keys-path {}`.", spec, keys)

View File

@ -93,7 +93,7 @@ impl ParityAccounts for ParityAccountsClient {
fn new_account_from_secret(&self, secret: RpcH256, pass: String) -> Result<RpcH160, Error> {
let store = self.account_provider()?;
let secret = Secret::from_slice(&secret.0)
let secret = Secret::from_unsafe_slice(&secret.0)
.map_err(|e| errors::account("Could not create account.", e))?;
store.insert_account(secret, &pass)
.map(Into::into)

View File

@ -58,7 +58,7 @@ impl SecretStoreClient {
/// Decrypt secret key using account' private key
fn decrypt_secret(&self, address: H160, password: String, key: Bytes) -> Result<Secret, Error> {
self.decrypt_key(address, password, key)
.and_then(|s| Secret::from_slice(&s).map_err(|e| errors::account("invalid secret", e)))
.and_then(|s| Secret::from_unsafe_slice(&s).map_err(|e| errors::account("invalid secret", e)))
}
}

View File

@ -302,7 +302,7 @@ fn rpc_eth_submit_hashrate() {
fn rpc_eth_sign() {
let tester = EthTester::default();
let account = tester.accounts_provider.insert_account(Secret::from_slice(&[69u8; 32]).unwrap(), "abcd").unwrap();
let account = tester.accounts_provider.insert_account(Secret::from_slice(&[69u8; 32]), "abcd").unwrap();
tester.accounts_provider.unlock_account_permanently(account, "abcd".into()).unwrap();
let _message = "0cc175b9c0f1b6a831c399e26977266192eb5ffee6ae2fec3ad71c777531578f".from_hex().unwrap();

View File

@ -200,7 +200,7 @@ fn should_sign_if_account_is_unlocked() {
// given
let tester = eth_signing();
let data = vec![5u8];
let acc = tester.accounts.insert_account(Secret::from_slice(&[69u8; 32]).unwrap(), "test").unwrap();
let acc = tester.accounts.insert_account(Secret::from_slice(&[69u8; 32]), "test").unwrap();
tester.accounts.unlock_account_permanently(acc, "test".into()).unwrap();
// when

View File

@ -1089,7 +1089,7 @@ mod tests {
use ethcrypto::DEFAULT_MAC;
use ethcrypto::ecies::decrypt;
let decrypt_shadows: Vec<_> = decrypted_secret.decrypt_shadows.unwrap().into_iter()
.map(|c| Secret::from_slice(&decrypt(key_pair.secret(), &DEFAULT_MAC, &c).unwrap()).unwrap())
.map(|c| Secret::from_slice(&decrypt(key_pair.secret(), &DEFAULT_MAC, &c).unwrap()))
.collect();
let decrypted_secret = math::decrypt_with_shadow_coefficients(decrypted_secret.decrypted_secret, decrypted_secret.common_point.unwrap(), decrypt_shadows).unwrap();
assert_eq!(decrypted_secret, SECRET_PLAIN.into());

View File

@ -13,6 +13,10 @@ case $1 in
OPTIONS=""
shift
;;
--no-run)
OPTIONS="--no-run"
shift
;;
*)
# unknown option
;;

View File

@ -1242,7 +1242,7 @@ fn load_key(path: &Path) -> Option<Secret> {
fn key_save_load() {
use ::devtools::RandomTempPath;
let temp_path = RandomTempPath::create_dir();
let key = Secret::from_slice(&H256::random()).unwrap();
let key = H256::random().into();
save_key(temp_path.as_path(), &key);
let r = load_key(temp_path.as_path());
assert_eq!(key, r.unwrap());