ethkey and ethstore use hash structures from bigint (#1851)

* Address renamed to H160 at bigint library level

* moved uint specific test from util to bigint library

* naming

* unifing hashes in progress

* unifing hashes

* cleanup redundant unwraps in tests

* fixed compiling
This commit is contained in:
Marek Kotewicz 2016-08-15 15:09:00 +02:00 committed by Gav Wood
parent e6d9fb2ad3
commit c39761c042
32 changed files with 245 additions and 396 deletions

1
Cargo.lock generated
View File

@ -494,6 +494,7 @@ dependencies = [
name = "ethkey"
version = "0.2.0"
dependencies = [
"bigint 0.1.0",
"eth-secp256k1 0.5.4 (git+https://github.com/ethcore/rust-secp256k1)",
"lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",

View File

@ -18,13 +18,14 @@
use std::{fs, fmt};
use std::collections::HashMap;
use std::time::{Instant, Duration};
use util::{Address as H160, H256, H520, Mutex, RwLock};
use std::path::PathBuf;
use ethjson::misc::AccountMeta;
use std::time::{Instant, Duration};
use util::{Mutex, RwLock};
use ethstore::{SecretStore, Error as SSError, SafeAccount, EthStore};
use ethstore::dir::{KeyDirectory};
use ethstore::ethkey::{Address as SSAddress, Message as SSMessage, Secret as SSSecret, Random, Generator};
use ethstore::ethkey::{Address, Message, Secret, Random, Generator};
use ethjson::misc::AccountMeta;
pub use ethstore::ethkey::Signature;
/// Type of unlock.
#[derive(Clone)]
@ -69,51 +70,9 @@ impl From<SSError> for Error {
}
}
macro_rules! impl_bridge_type {
($name: ident, $size: expr, $core: ident, $store: ident) => {
/// Primitive
pub struct $name([u8; $size]);
impl From<[u8; $size]> for $name {
fn from(s: [u8; $size]) -> Self {
$name(s)
}
}
impl From<$core> for $name {
fn from(s: $core) -> Self {
$name(s.0)
}
}
impl From<$store> for $name {
fn from(s: $store) -> Self {
$name(s.into())
}
}
impl Into<$core> for $name {
fn into(self) -> $core {
$core(self.0)
}
}
impl Into<$store> for $name {
fn into(self) -> $store {
$store::from(self.0)
}
}
}
}
impl_bridge_type!(Secret, 32, H256, SSSecret);
impl_bridge_type!(Message, 32, H256, SSMessage);
impl_bridge_type!(Address, 20, H160, SSAddress);
#[derive(Default)]
struct NullDir {
accounts: RwLock<HashMap<SSAddress, SafeAccount>>,
accounts: RwLock<HashMap<Address, SafeAccount>>,
}
impl KeyDirectory for NullDir {
@ -126,7 +85,7 @@ impl KeyDirectory for NullDir {
Ok(account)
}
fn remove(&self, address: &SSAddress) -> Result<(), SSError> {
fn remove(&self, address: &Address) -> Result<(), SSError> {
self.accounts.write().remove(address);
Ok(())
}
@ -135,7 +94,7 @@ impl KeyDirectory for NullDir {
/// Disk-backed map from Address to String. Uses JSON.
struct AddressBook {
path: PathBuf,
cache: HashMap<H160, AccountMeta>,
cache: HashMap<Address, AccountMeta>,
}
impl AddressBook {
@ -152,23 +111,23 @@ impl AddressBook {
r
}
pub fn get(&self) -> HashMap<H160, AccountMeta> {
pub fn get(&self) -> HashMap<Address, AccountMeta> {
self.cache.clone()
}
pub fn set_name(&mut self, a: H160, name: String) {
pub fn set_name(&mut self, a: Address, name: String) {
let mut x = self.cache.get(&a)
.map(|a| a.clone())
.unwrap_or(AccountMeta{name: Default::default(), meta: "{}".to_owned(), uuid: None});
.unwrap_or(AccountMeta {name: Default::default(), meta: "{}".to_owned(), uuid: None});
x.name = name;
self.cache.insert(a, x);
self.save();
}
pub fn set_meta(&mut self, a: H160, meta: String) {
pub fn set_meta(&mut self, a: Address, meta: String) {
let mut x = self.cache.get(&a)
.map(|a| a.clone())
.unwrap_or(AccountMeta{name: "Anonymous".to_owned(), meta: Default::default(), uuid: None});
.unwrap_or(AccountMeta {name: "Anonymous".to_owned(), meta: Default::default(), uuid: None});
x.meta = meta;
self.cache.insert(a, x);
self.save();
@ -197,7 +156,7 @@ impl AddressBook {
/// Account management.
/// Responsible for unlocking accounts.
pub struct AccountProvider {
unlocked: Mutex<HashMap<SSAddress, AccountData>>,
unlocked: Mutex<HashMap<Address, AccountData>>,
sstore: Box<SecretStore>,
address_book: Mutex<AddressBook>,
}
@ -222,67 +181,63 @@ impl AccountProvider {
}
/// Creates new random account.
pub fn new_account(&self, password: &str) -> Result<H160, Error> {
pub fn new_account(&self, password: &str) -> Result<Address, Error> {
let secret = Random.generate().unwrap().secret().clone();
let address = try!(self.sstore.insert_account(secret, password));
Ok(Address::from(address).into())
Ok(address)
}
/// Inserts new account into underlying store.
/// Does not unlock account!
pub fn insert_account<S>(&self, secret: S, password: &str) -> Result<H160, Error> where Secret: From<S> {
let s = Secret::from(secret);
let address = try!(self.sstore.insert_account(s.into(), password));
Ok(Address::from(address).into())
pub fn insert_account(&self, secret: Secret, password: &str) -> Result<Address, Error> {
let address = try!(self.sstore.insert_account(secret, password));
Ok(address)
}
/// Import a new presale wallet.
pub fn import_presale(&self, presale_json: &[u8], password: &str) -> Result<H160, Error> {
pub fn import_presale(&self, presale_json: &[u8], password: &str) -> Result<Address, Error> {
let address = try!(self.sstore.import_presale(presale_json, password));
Ok(Address::from(address).into())
}
/// Import a new presale wallet.
pub fn import_wallet(&self, json: &[u8], password: &str) -> Result<H160, Error> {
pub fn import_wallet(&self, json: &[u8], password: &str) -> Result<Address, Error> {
let address = try!(self.sstore.import_wallet(json, password));
Ok(Address::from(address).into())
}
/// Returns addresses of all accounts.
pub fn accounts(&self) -> Result<Vec<H160>, Error> {
let accounts = try!(self.sstore.accounts()).into_iter().map(|a| H160(a.into())).collect();
pub fn accounts(&self) -> Result<Vec<Address>, Error> {
let accounts = try!(self.sstore.accounts());
Ok(accounts)
}
/// Returns each address along with metadata.
pub fn addresses_info(&self) -> Result<HashMap<H160, AccountMeta>, Error> {
pub fn addresses_info(&self) -> Result<HashMap<Address, AccountMeta>, Error> {
Ok(self.address_book.lock().get())
}
/// Returns each address along with metadata.
pub fn set_address_name<A>(&self, account: A, name: String) -> Result<(), Error> where Address: From<A> {
let account = Address::from(account).into();
pub fn set_address_name(&self, account: Address, name: String) -> Result<(), Error> {
Ok(self.address_book.lock().set_name(account, name))
}
/// Returns each address along with metadata.
pub fn set_address_meta<A>(&self, account: A, meta: String) -> Result<(), Error> where Address: From<A> {
let account = Address::from(account).into();
pub fn set_address_meta(&self, account: Address, meta: String) -> Result<(), Error> {
Ok(self.address_book.lock().set_meta(account, meta))
}
/// Returns each account along with name and meta.
pub fn accounts_info(&self) -> Result<HashMap<H160, AccountMeta>, Error> {
let r: HashMap<H160, AccountMeta> = try!(self.sstore.accounts())
pub fn accounts_info(&self) -> Result<HashMap<Address, AccountMeta>, Error> {
let r: HashMap<Address, AccountMeta> = try!(self.sstore.accounts())
.into_iter()
.map(|a| (H160(a.clone().into()), self.account_meta(a).unwrap_or_else(|_| Default::default())))
.map(|a| (a.clone(), self.account_meta(a).unwrap_or_else(|_| Default::default())))
.collect();
Ok(r)
}
/// Returns each account along with name and meta.
pub fn account_meta<A>(&self, account: A) -> Result<AccountMeta, Error> where Address: From<A> {
let account = Address::from(account).into();
pub fn account_meta(&self, account: Address) -> Result<AccountMeta, Error> {
Ok(AccountMeta {
name: try!(self.sstore.name(&account)),
meta: try!(self.sstore.meta(&account)),
@ -291,23 +246,19 @@ impl AccountProvider {
}
/// Returns each account along with name and meta.
pub fn set_account_name<A>(&self, account: A, name: String) -> Result<(), Error> where Address: From<A> {
let account = Address::from(account).into();
pub fn set_account_name(&self, account: Address, name: String) -> Result<(), Error> {
try!(self.sstore.set_name(&account, name));
Ok(())
}
/// Returns each account along with name and meta.
pub fn set_account_meta<A>(&self, account: A, meta: String) -> Result<(), Error> where Address: From<A> {
let account = Address::from(account).into();
pub fn set_account_meta(&self, account: Address, meta: String) -> Result<(), Error> {
try!(self.sstore.set_meta(&account, meta));
Ok(())
}
/// Helper method used for unlocking accounts.
fn unlock_account<A>(&self, account: A, password: String, unlock: Unlock) -> Result<(), Error> where Address: From<A> {
let a = Address::from(account);
let account = a.into();
fn unlock_account(&self, account: Address, password: String, unlock: Unlock) -> Result<(), Error> {
// verify password by signing dump message
// result may be discarded
let _ = try!(self.sstore.sign(&account, &password, &Default::default()));
@ -330,32 +281,28 @@ impl AccountProvider {
}
/// Unlocks account permanently.
pub fn unlock_account_permanently<A>(&self, account: A, password: String) -> Result<(), Error> where Address: From<A> {
pub fn unlock_account_permanently(&self, account: Address, password: String) -> Result<(), Error> {
self.unlock_account(account, password, Unlock::Perm)
}
/// Unlocks account temporarily (for one signing).
pub fn unlock_account_temporarily<A>(&self, account: A, password: String) -> Result<(), Error> where Address: From<A> {
pub fn unlock_account_temporarily(&self, account: Address, password: String) -> Result<(), Error> {
self.unlock_account(account, password, Unlock::Temp)
}
/// Unlocks account temporarily with a timeout.
pub fn unlock_account_timed<A>(&self, account: A, password: String, duration_ms: u32) -> Result<(), Error> where Address: From<A> {
pub fn unlock_account_timed(&self, account: Address, password: String, duration_ms: u32) -> Result<(), Error> {
self.unlock_account(account, password, Unlock::Timed((Instant::now(), duration_ms)))
}
/// Checks if given account is unlocked
pub fn is_unlocked<A>(&self, account: A) -> bool where Address: From<A> {
let account = Address::from(account).into();
pub fn is_unlocked(&self, account: Address) -> bool {
let unlocked = self.unlocked.lock();
unlocked.get(&account).is_some()
}
/// Signs the message. Account must be unlocked.
pub fn sign<A, M>(&self, account: A, message: M) -> Result<H520, Error> where Address: From<A>, Message: From<M> {
let account = Address::from(account).into();
let message = Message::from(message).into();
pub fn sign(&self, account: Address, message: Message) -> Result<Signature, Error> {
let data = {
let mut unlocked = self.unlocked.lock();
let data = try!(unlocked.get(&account).ok_or(Error::NotUnlocked)).clone();
@ -372,26 +319,23 @@ impl AccountProvider {
};
let signature = try!(self.sstore.sign(&account, &data.password, &message));
Ok(H520(signature.into()))
Ok(signature)
}
/// Unlocks an account, signs the message, and locks it again.
pub fn sign_with_password<A, M>(&self, account: A, password: String, message: M) -> Result<H520, Error> where Address: From<A>, Message: From<M> {
let account = Address::from(account).into();
let message = Message::from(message).into();
pub fn sign_with_password(&self, account: Address, password: String, message: Message) -> Result<Signature, Error> {
let signature = try!(self.sstore.sign(&account, &password, &message));
Ok(H520(signature.into()))
Ok(signature)
}
/// Returns the underlying `SecretStore` reference if one exists.
pub fn list_geth_accounts(&self, testnet: bool) -> Vec<H160> {
pub fn list_geth_accounts(&self, testnet: bool) -> Vec<Address> {
self.sstore.list_geth_accounts(testnet).into_iter().map(|a| Address::from(a).into()).collect()
}
/// Returns the underlying `SecretStore` reference if one exists.
pub fn import_geth_accounts(&self, desired: Vec<H160>, testnet: bool) -> Result<Vec<H160>, Error> {
let desired = desired.into_iter().map(|a| Address::from(a).into()).collect();
Ok(try!(self.sstore.import_geth_accounts(desired, testnet)).into_iter().map(|a| Address::from(a).into()).collect())
pub fn import_geth_accounts(&self, desired: Vec<Address>, testnet: bool) -> Result<Vec<Address>, Error> {
self.sstore.import_geth_accounts(desired, testnet).map_err(Into::into)
}
}
@ -422,8 +366,8 @@ mod tests {
assert!(ap.insert_account(kp.secret().clone(), "test").is_ok());
assert!(ap.unlock_account_temporarily(kp.address(), "test1".into()).is_err());
assert!(ap.unlock_account_temporarily(kp.address(), "test".into()).is_ok());
assert!(ap.sign(kp.address(), [0u8; 32]).is_ok());
assert!(ap.sign(kp.address(), [0u8; 32]).is_err());
assert!(ap.sign(kp.address(), Default::default()).is_ok());
assert!(ap.sign(kp.address(), Default::default()).is_err());
}
#[test]
@ -433,11 +377,11 @@ mod tests {
assert!(ap.insert_account(kp.secret().clone(), "test").is_ok());
assert!(ap.unlock_account_permanently(kp.address(), "test1".into()).is_err());
assert!(ap.unlock_account_permanently(kp.address(), "test".into()).is_ok());
assert!(ap.sign(kp.address(), [0u8; 32]).is_ok());
assert!(ap.sign(kp.address(), [0u8; 32]).is_ok());
assert!(ap.sign(kp.address(), Default::default()).is_ok());
assert!(ap.sign(kp.address(), Default::default()).is_ok());
assert!(ap.unlock_account_temporarily(kp.address(), "test".into()).is_ok());
assert!(ap.sign(kp.address(), [0u8; 32]).is_ok());
assert!(ap.sign(kp.address(), [0u8; 32]).is_ok());
assert!(ap.sign(kp.address(), Default::default()).is_ok());
assert!(ap.sign(kp.address(), Default::default()).is_ok());
}
#[test]
@ -447,8 +391,8 @@ mod tests {
assert!(ap.insert_account(kp.secret().clone(), "test").is_ok());
assert!(ap.unlock_account_timed(kp.address(), "test1".into(), 2000).is_err());
assert!(ap.unlock_account_timed(kp.address(), "test".into(), 2000).is_ok());
assert!(ap.sign(kp.address(), [0u8; 32]).is_ok());
assert!(ap.sign(kp.address(), Default::default()).is_ok());
::std::thread::sleep(Duration::from_millis(2000));
assert!(ap.sign(kp.address(), [0u8; 32]).is_err());
assert!(ap.sign(kp.address(), Default::default()).is_err());
}
}

View File

@ -109,7 +109,7 @@ impl Engine for BasicAuthority {
let message = header.bare_hash();
// account should be pernamently unlocked, otherwise sealing will fail
if let Ok(signature) = ap.sign(*block.header().author(), message) {
return Some(vec![encode(&signature).to_vec()]);
return Some(vec![encode(&(&*signature as &[u8])).to_vec()]);
} else {
trace!(target: "basicauthority", "generate_seal: FAIL: accounts secret key unavailable");
}

View File

@ -15,7 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::collections::BTreeMap;
use util::hash::Address;
use util::Address;
use builtin::Builtin;
use engines::Engine;
use spec::CommonParams;

View File

@ -15,7 +15,7 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::collections::BTreeMap;
use util::hash::Address;
use util::Address;
use builtin::Builtin;
use engines::Engine;
use spec::CommonParams;

View File

@ -16,7 +16,7 @@
//! Interface for Evm externalities.
use util::common::*;
use util::*;
use evm::{self, Schedule};
use env_info::*;
use types::executed::CallType;

View File

@ -20,7 +20,7 @@
use std::collections::HashMap;
use util::Bytes;
use util::hash::{Address, FixedHash, H256};
use util::{Address, FixedHash, H256};
use util::kvdb::Database;
use util::migration::{Batch, Config, Error, Migration, SimpleMigration, Progress};
use util::rlp::{decode, Rlp, RlpStream, Stream, View};

View File

@ -144,7 +144,7 @@ mod tests {
use snapshot::tests::helpers::fill_storage;
use util::{SHA3_NULL_RLP, SHA3_EMPTY};
use util::hash::{Address, FixedHash, H256};
use util::{Address, FixedHash, H256};
use util::rlp::{UntrustedRlp, View};
use super::Account;

View File

@ -422,8 +422,10 @@ impl Clone for State {
#[cfg(test)]
mod tests {
use std::str::FromStr;
use rustc_serialize::hex::FromHex;
use super::*;
use util::common::*;
use util::{U256, H256, FixedHash, Address, Hashable};
use account::*;
use tests::helpers::*;
use devtools::*;

View File

@ -16,14 +16,13 @@
//! Blockchain filter
use util::hash::*;
use util::sha3::*;
use std::mem;
use std::collections::VecDeque;
use util::{Address, H256, Hashable, H2048};
use util::bloom::Bloomable;
use client::BlockID;
use log_entry::LogEntry;
use ipc::binary::BinaryConvertError;
use std::mem;
use std::collections::VecDeque;
/// Blockchain Filter.
#[derive(Binary)]
@ -74,11 +73,11 @@ impl Filter {
let blooms = match self.address {
Some(ref addresses) if !addresses.is_empty() =>
addresses.iter().map(|ref address| {
let mut bloom = H2048::new();
let mut bloom = H2048::default();
bloom.shift_bloomed(&address.sha3());
bloom
}).collect(),
_ => vec![H2048::new()]
_ => vec![H2048::default()]
};
self.topics.iter().fold(blooms, |bs, topic| match *topic {
@ -109,8 +108,7 @@ impl Filter {
#[cfg(test)]
mod tests {
use std::str::FromStr;
use util::hash::*;
use util::FixedHash;
use filter::Filter;
use client::BlockID;
use log_entry::LogEntry;
@ -135,9 +133,9 @@ mod tests {
let filter = Filter {
from_block: BlockID::Earliest,
to_block: BlockID::Latest,
address: Some(vec![Address::from_str("b372018f3be9e171df0581136b59d2faf73a7d5d").unwrap()]),
address: Some(vec!["b372018f3be9e171df0581136b59d2faf73a7d5d".into()]),
topics: vec![
Some(vec![H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap()]),
Some(vec!["ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9".into()]),
None,
None,
None,
@ -145,7 +143,7 @@ mod tests {
};
let possibilities = filter.bloom_possibilities();
assert_eq!(possibilities, vec![H2048::from_str("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000004000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000").unwrap()]);
assert_eq!(possibilities, vec!["00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000004000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000".into()]);
}
#[test]
@ -153,17 +151,17 @@ mod tests {
let filter = Filter {
from_block: BlockID::Earliest,
to_block: BlockID::Latest,
address: Some(vec![Address::from_str("b372018f3be9e171df0581136b59d2faf73a7d5d").unwrap()]),
address: Some(vec!["b372018f3be9e171df0581136b59d2faf73a7d5d".into()]),
topics: vec![
Some(vec![H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap()]),
Some(vec![H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap()]),
Some(vec!["ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9".into()]),
Some(vec!["ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9".into()]),
None,
None,
]
};
let possibilities = filter.bloom_possibilities();
assert_eq!(possibilities, vec![H2048::from_str("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000004000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000").unwrap()]);
assert_eq!(possibilities, vec!["00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000004000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000".into()]);
}
#[test]
@ -172,19 +170,19 @@ mod tests {
from_block: BlockID::Earliest,
to_block: BlockID::Latest,
address: Some(vec![
Address::from_str("b372018f3be9e171df0581136b59d2faf73a7d5d").unwrap(),
Address::from_str("b372018f3be9e171df0581136b59d2faf73a7d5d").unwrap(),
"b372018f3be9e171df0581136b59d2faf73a7d5d".into(),
"b372018f3be9e171df0581136b59d2faf73a7d5d".into(),
]),
topics: vec![
Some(vec![
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap(),
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap()
"ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9".into(),
"ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9".into()
]),
Some(vec![
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap(),
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap()
"ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9".into(),
"ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9".into()
]),
Some(vec![H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap()]),
Some(vec!["ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9".into()]),
None
]
};
@ -192,7 +190,7 @@ mod tests {
// number of possibilites should be equal 2 * 2 * 2 * 1 = 8
let possibilities = filter.bloom_possibilities();
assert_eq!(possibilities.len(), 8);
assert_eq!(possibilities[0], H2048::from_str("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000004000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000").unwrap());
assert_eq!(possibilities[0], "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000004000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000".into());
}
#[test]
@ -200,39 +198,39 @@ mod tests {
let filter = Filter {
from_block: BlockID::Earliest,
to_block: BlockID::Latest,
address: Some(vec![Address::from_str("b372018f3be9e171df0581136b59d2faf73a7d5d").unwrap()]),
address: Some(vec!["b372018f3be9e171df0581136b59d2faf73a7d5d".into()]),
topics: vec![
Some(vec![H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap()]),
Some(vec![H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23fa").unwrap()]),
Some(vec!["ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9".into()]),
Some(vec!["ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23fa".into()]),
None,
None,
]
};
let entry0 = LogEntry {
address: Address::from_str("b372018f3be9e171df0581136b59d2faf73a7d5d").unwrap(),
address: "b372018f3be9e171df0581136b59d2faf73a7d5d".into(),
topics: vec![
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap(),
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23fa").unwrap(),
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap(),
"ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9".into(),
"ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23fa".into(),
"ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9".into(),
],
data: vec![]
};
let entry1 = LogEntry {
address: Address::from_str("b372018f3be9e171df0581136b59d2faf73a7d5e").unwrap(),
address: "b372018f3be9e171df0581136b59d2faf73a7d5e".into(),
topics: vec![
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap(),
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23fa").unwrap(),
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap(),
"ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9".into(),
"ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23fa".into(),
"ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9".into(),
],
data: vec![]
};
let entry2 = LogEntry {
address: Address::from_str("b372018f3be9e171df0581136b59d2faf73a7d5d").unwrap(),
address: "b372018f3be9e171df0581136b59d2faf73a7d5d".into(),
topics: vec![
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap(),
"ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9".into(),
],
data: vec![]
};

View File

@ -30,6 +30,7 @@ use evm::Schedule;
use header::BlockNumber;
use ethjson;
use ipc::binary::BinaryConvertError;
use ethstore::ethkey::Signature as EthkeySignature;
#[derive(Debug, Clone, PartialEq, Eq, Binary)]
/// Transaction action type.
@ -142,11 +143,12 @@ impl Transaction {
/// Signs the transaction as coming from `sender`.
pub fn sign(self, secret: &Secret) -> SignedTransaction {
let sig = ec::sign(secret, &self.hash()).unwrap();
self.with_signature(sig)
self.with_signature(sig.into())
}
/// Signs the transaction with signature.
pub fn with_signature(self, sig: H520) -> SignedTransaction {
pub fn with_signature(self, sig: EthkeySignature) -> SignedTransaction {
let sig: H520 = sig.into();
let (r, s, v) = signature_to_rsv(&sig);
SignedTransaction {
unsigned: self,

View File

@ -10,6 +10,7 @@ tiny-keccak = "1.0"
eth-secp256k1 = { git = "https://github.com/ethcore/rust-secp256k1" }
rustc-serialize = "0.3"
docopt = { version = "0.6", optional = true }
bigint = { path = "../util/bigint" }
[features]
default = []

View File

@ -18,12 +18,11 @@ extern crate docopt;
extern crate rustc_serialize;
extern crate ethkey;
use std::str::FromStr;
use std::{env, fmt, process};
use std::num::ParseIntError;
use docopt::Docopt;
use rustc_serialize::hex::{FromHex, FromHexError};
use ethkey::{KeyPair, Random, Brain, Prefix, Error as EthkeyError, Generator, Secret, Message, Public, Signature, Address, sign, verify_public, verify_address};
use ethkey::{KeyPair, Random, Brain, Prefix, Error as EthkeyError, Generator, sign, verify_public, verify_address};
pub const USAGE: &'static str = r#"
Ethereum keys generator.
@ -148,9 +147,9 @@ fn main() {
fn display(keypair: KeyPair, mode: DisplayMode) -> String {
match mode {
DisplayMode::KeyPair => format!("{}", keypair),
DisplayMode::Secret => format!("{}", keypair.secret()),
DisplayMode::Public => format!("{}", keypair.public()),
DisplayMode::Address => format!("{}", keypair.address()),
DisplayMode::Secret => format!("{:?}", keypair.secret()),
DisplayMode::Public => format!("{:?}", keypair.public()),
DisplayMode::Address => format!("{:?}", keypair.address()),
}
}
@ -161,7 +160,7 @@ fn execute<S, I>(command: I) -> Result<String, Error> where I: IntoIterator<Item
return if args.cmd_info {
let display_mode = DisplayMode::new(&args);
let secret = try!(Secret::from_str(&args.arg_secret));
let secret = try!(args.arg_secret.parse().map_err(|_| EthkeyError::InvalidSecret));
let keypair = try!(KeyPair::from_secret(secret));
Ok(display(keypair, display_mode))
} else if args.cmd_generate {
@ -179,18 +178,18 @@ fn execute<S, I>(command: I) -> Result<String, Error> where I: IntoIterator<Item
};
Ok(display(try!(keypair), display_mode))
} else if args.cmd_sign {
let secret = try!(Secret::from_str(&args.arg_secret));
let message = try!(Message::from_str(&args.arg_message));
let secret = try!(args.arg_secret.parse().map_err(|_| EthkeyError::InvalidSecret));
let message = try!(args.arg_message.parse().map_err(|_| EthkeyError::InvalidMessage));
let signature = try!(sign(&secret, &message));
Ok(format!("{}", signature))
} else if args.cmd_verify {
let signature = try!(Signature::from_str(&args.arg_signature));
let message = try!(Message::from_str(&args.arg_message));
let signature = try!(args.arg_signature.parse().map_err(|_| EthkeyError::InvalidSignature));
let message = try!(args.arg_message.parse().map_err(|_| EthkeyError::InvalidMessage));
let ok = if args.cmd_public {
let public = try!(Public::from_str(&args.arg_public));
let public = try!(args.arg_public.parse().map_err(|_| EthkeyError::InvalidPublic));
try!(verify_public(&public, &signature, &message))
} else if args.cmd_address {
let address = try!(Address::from_str(&args.arg_address));
let address = try!(args.arg_address.parse().map_err(|_| EthkeyError::InvalidAddress));
try!(verify_address(&address, &signature, &message))
} else {
unreachable!();
@ -212,7 +211,7 @@ mod tests {
.map(Into::into)
.collect::<Vec<String>>();
let expected =
let expected =
"secret: 17d08f5fe8c77af811caa0c9a187e668ce3b74a99acc3f6d976f075fa8e0be55
public: 689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124
address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned();
@ -226,7 +225,7 @@ address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned();
.map(Into::into)
.collect::<Vec<String>>();
let expected =
let expected =
"secret: 17d08f5fe8c77af811caa0c9a187e668ce3b74a99acc3f6d976f075fa8e0be55
public: 689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124
address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned();
@ -272,7 +271,7 @@ address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned();
.into_iter()
.map(Into::into)
.collect::<Vec<String>>();
let expected = "c1878cf60417151c766a712653d26ef350c8c75393458b7a9be715f053215af63dfd3b02c2ae65a8677917a8efa3172acb71cb90196e42106953ea0363c5aaf200".to_owned();
assert_eq!(execute(command).unwrap(), expected);
}

View File

@ -38,8 +38,8 @@ pub enum Error {
impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let msg = match *self {
Error::InvalidSecret => "Invalid secret key".into(),
Error::InvalidPublic => "Invalid public key".into(),
Error::InvalidSecret => "Invalid secret".into(),
Error::InvalidPublic => "Invalid public".into(),
Error::InvalidAddress => "Invalid address".into(),
Error::InvalidSignature => "Invalid EC signature".into(),
Error::InvalidMessage => "Invalid AES message".into(),

View File

@ -20,13 +20,13 @@ extern crate lazy_static;
extern crate tiny_keccak;
extern crate secp256k1;
extern crate rustc_serialize;
extern crate bigint;
mod brain;
mod error;
mod keypair;
mod keccak;
mod prefix;
mod primitive;
mod random;
mod signature;
@ -43,7 +43,13 @@ pub trait Generator {
pub use self::brain::Brain;
pub use self::error::Error;
pub use self::keypair::{KeyPair, public_to_address};
pub use self::primitive::{Secret, Public, Address, Message};
pub use self::prefix::Prefix;
pub use self::random::Random;
pub use self::signature::{sign, verify_public, verify_address, recover, Signature};
use bigint::hash::{H160, H256, H512};
pub type Address = H160;
pub type Secret = H256;
pub type Message = H256;
pub type Public = H512;

View File

@ -14,125 +14,4 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::ops::{Deref, DerefMut};
use std::{fmt, cmp, hash};
use std::str::FromStr;
use rustc_serialize::hex::{ToHex, FromHex};
use Error;
macro_rules! impl_primitive {
($name: ident, $size: expr, $err: expr) => {
#[repr(C)]
#[derive(Eq)]
pub struct $name([u8; $size]);
impl fmt::Debug for $name {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(f, "{}", self.to_hex())
}
}
impl fmt::Display for $name {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(f, "{}", self.to_hex())
}
}
impl FromStr for $name {
type Err = Error;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.from_hex() {
Ok(ref hex) if hex.len() == $size => {
let mut res = $name::default();
res.copy_from_slice(hex);
Ok(res)
},
_ => Err($err)
}
}
}
impl PartialEq for $name {
fn eq(&self, other: &Self) -> bool {
let self_ref: &[u8] = &self.0;
let other_ref: &[u8] = &other.0;
self_ref == other_ref
}
}
impl PartialOrd for $name {
fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
let self_ref: &[u8] = &self.0;
let other_ref: &[u8] = &other.0;
self_ref.partial_cmp(other_ref)
}
}
impl Ord for $name {
fn cmp(&self, other: &Self) -> cmp::Ordering {
let self_ref: &[u8] = &self.0;
let other_ref: &[u8] = &other.0;
self_ref.cmp(other_ref)
}
}
impl Clone for $name {
fn clone(&self) -> Self {
let mut res = Self::default();
res.copy_from_slice(&self.0);
res
}
}
impl Default for $name {
fn default() -> Self {
$name([0u8; $size])
}
}
impl From<[u8; $size]> for $name {
fn from(s: [u8; $size]) -> Self {
$name(s)
}
}
impl Into<[u8; $size]> for $name {
fn into(self) -> [u8; $size] {
self.0
}
}
impl hash::Hash for $name {
fn hash<H>(&self, state: &mut H) where H: hash::Hasher {
let self_ref: &[u8] = &self.0;
self_ref.hash(state)
}
}
impl Deref for $name {
type Target = [u8; $size];
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for $name {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
}
}
impl_primitive!(Address, 20, Error::InvalidAddress);
impl_primitive!(Secret, 32, Error::InvalidSecret);
impl_primitive!(Message, 32, Error::InvalidMessage);
impl_primitive!(Public, 64, Error::InvalidPublic);
#[cfg(test)]
mod tests {
}

View File

@ -15,11 +15,13 @@
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::ops::{Deref, DerefMut};
use std::cmp::PartialEq;
use std::{mem, fmt};
use std::str::FromStr;
use secp256k1::{Message as SecpMessage, RecoverableSignature, RecoveryId, Error as SecpError};
use secp256k1::key::{SecretKey, PublicKey};
use rustc_serialize::hex::{ToHex, FromHex};
use bigint::hash::H520;
use {Secret, Public, SECP256K1, Error, Message, public_to_address, Address};
#[repr(C)]
@ -45,7 +47,7 @@ impl Signature {
// manual implementation large arrays don't have trait impls by default.
// remove when integer generics exist
impl ::std::cmp::PartialEq for Signature {
impl PartialEq for Signature {
fn eq(&self, other: &Self) -> bool {
&self.0[..] == &other.0[..]
}
@ -101,6 +103,18 @@ impl Into<[u8; 65]> for Signature {
}
}
impl From<Signature> for H520 {
fn from(s: Signature) -> Self {
H520::from(s.0)
}
}
impl From<H520> for Signature {
fn from(bytes: H520) -> Self {
Signature(bytes.into())
}
}
impl Deref for Signature {
type Target = [u8; 65];

View File

@ -21,9 +21,8 @@ extern crate ethstore;
use std::{env, process, fs};
use std::io::Read;
use std::ops::Deref;
use std::str::FromStr;
use docopt::Docopt;
use ethstore::ethkey::{Secret, Address, Message};
use ethstore::ethkey::Address;
use ethstore::dir::{KeyDirectory, ParityDirectory, DiskDirectory, GethDirectory, DirectoryType};
use ethstore::{EthStore, SecretStore, import_accounts, Error, PresaleWallet};
@ -127,12 +126,12 @@ fn execute<S, I>(command: I) -> Result<String, Error> where I: IntoIterator<Item
let store = try!(EthStore::open(try!(key_dir(&args.flag_dir))));
return if args.cmd_insert {
let secret = try!(Secret::from_str(&args.arg_secret));
let secret = try!(args.arg_secret.parse().map_err(|_| Error::InvalidSecret));
let password = try!(load_password(&args.arg_password));
let address = try!(store.insert_account(secret, &password));
Ok(format!("{}", address))
} else if args.cmd_change_pwd {
let address = try!(Address::from_str(&args.arg_address));
let address = try!(args.arg_address.parse().map_err(|_| Error::InvalidAccount));
let old_pwd = try!(load_password(&args.arg_old_pwd));
let new_pwd = try!(load_password(&args.arg_new_pwd));
let ok = store.change_password(&address, &old_pwd, &new_pwd).is_ok();
@ -152,13 +151,13 @@ fn execute<S, I>(command: I) -> Result<String, Error> where I: IntoIterator<Item
let address = try!(store.insert_account(kp.secret().clone(), &password));
Ok(format!("{}", address))
} else if args.cmd_remove {
let address = try!(Address::from_str(&args.arg_address));
let address = try!(args.arg_address.parse().map_err(|_| Error::InvalidAccount));
let password = try!(load_password(&args.arg_password));
let ok = store.remove_account(&address, &password).is_ok();
Ok(format!("{}", ok))
} else if args.cmd_sign {
let address = try!(Address::from_str(&args.arg_address));
let message = try!(Message::from_str(&args.arg_message));
let address = try!(args.arg_address.parse().map_err(|_| Error::InvalidAccount));
let message = try!(args.arg_message.parse().map_err(|_| Error::InvalidMessage));
let password = try!(load_password(&args.arg_password));
let signature = try!(store.sign(&address, &password, &message));
Ok(format!("{}", signature))

View File

@ -24,6 +24,7 @@ pub enum Error {
InvalidPassword,
InvalidSecret,
InvalidAccount,
InvalidMessage,
InvalidKeyFile(String),
CreationFailed,
EthKey(EthKeyError),
@ -37,6 +38,7 @@ impl fmt::Display for Error {
Error::InvalidPassword => "Invalid password".into(),
Error::InvalidSecret => "Invalid secret".into(),
Error::InvalidAccount => "Invalid account".into(),
Error::InvalidMessage => "Invalid message".into(),
Error::InvalidKeyFile(ref reason) => format!("Invalid key file: {}", reason),
Error::CreationFailed => "Account creation failed".into(),
Error::EthKey(ref err) => err.to_string(),

View File

@ -20,7 +20,7 @@ use std::str::FromStr;
use serde::{Deserialize, Deserializer, Serialize, Serializer, Error};
use serde::de::Visitor;
use rustc_serialize::hex::ToHex;
use util::hash::{H64 as Hash64, Address as Hash160, H256 as Hash256, H2048 as Hash2048};
use util::hash::{H64 as Hash64, H160 as Hash160, H256 as Hash256, H2048 as Hash2048};
macro_rules! impl_hash {

View File

@ -30,7 +30,7 @@ use ethcore::account_provider::AccountProvider;
use devtools::RandomTempPath;
use util::Hashable;
use io::IoChannel;
use util::{U256, H256, Uint};
use util::{U256, H256, Uint, Address};
use jsonrpc_core::IoHandler;
use ethjson::blockchain::BlockChain;
@ -416,7 +416,7 @@ fn verify_transaction_counts(name: String, chain: BlockChain) {
#[test]
fn starting_nonce_test() {
let tester = EthTester::from_spec(Spec::load(POSITIVE_NONCE_SPEC));
let address = ::util::hash::Address::from(10);
let address = Address::from(10);
let sample = tester.handler.handle_request(&(r#"
{

View File

@ -19,9 +19,7 @@ use std::collections::HashMap;
use std::sync::Arc;
use std::time::{Instant, Duration};
use jsonrpc_core::IoHandler;
use util::hash::{Address, H256, FixedHash};
use util::{Uint, U256};
use util::Mutex;
use util::{Uint, U256, Address, H256, FixedHash, Mutex};
use ethcore::account_provider::AccountProvider;
use ethcore::client::{TestBlockChainClient, EachBlockWith, Executed, TransactionID};
use ethcore::log_entry::{LocalizedLogEntry, LogEntry};
@ -187,7 +185,7 @@ fn rpc_eth_sign() {
],
"id": 1
}"#;
let res = r#"{"jsonrpc":"2.0","result":""#.to_owned() + &format!("0x{:?}", signed) + r#"","id":1}"#;
let res = r#"{"jsonrpc":"2.0","result":""#.to_owned() + &format!("0x{}", signed) + r#"","id":1}"#;
assert_eq!(tester.io.handle_request(&req), Some(res));
}

View File

@ -185,7 +185,7 @@ fn should_sign_if_account_is_unlocked() {
],
"id": 1
}"#;
let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:?}", signature).as_ref() + r#"","id":1}"#;
let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{}", signature).as_ref() + r#"","id":1}"#;
assert_eq!(tester.io.handle_request(&request), Some(response.to_owned()));
assert_eq!(tester.queue.requests().len(), 0);
}

View File

@ -20,7 +20,7 @@ use std::cmp::Ordering;
use std::hash::{Hash, Hasher};
use serde;
use rustc_serialize::hex::{ToHex, FromHex};
use util::{H64 as Eth64, H256 as EthH256, H520 as EthH520, H2048 as Eth2048, Address};
use util::{H64 as Eth64, H256 as EthH256, H520 as EthH520, H2048 as Eth2048, H160 as Eth160};
macro_rules! impl_hash {
($name: ident, $other: ident, $size: expr) => {
@ -143,7 +143,7 @@ macro_rules! impl_hash {
}
impl_hash!(H64, Eth64, 8);
impl_hash!(H160, Address, 20);
impl_hash!(H160, Eth160, 20);
impl_hash!(H256, EthH256, 32);
impl_hash!(H520, EthH520, 65);
impl_hash!(H2048, Eth2048, 256);

View File

@ -17,8 +17,8 @@
//! General hash types, a fixed-size raw-data type used as the output of hash functions.
use std::{ops, fmt, cmp};
use std::cmp::*;
use std::ops::*;
use std::cmp::{min, Ordering};
use std::ops::{Deref, DerefMut, BitXor, BitAnd, BitOr, IndexMut, Index};
use std::hash::{Hash, Hasher, BuildHasherDefault};
use std::collections::{HashMap, HashSet};
use std::str::FromStr;
@ -75,6 +75,12 @@ macro_rules! impl_hash {
}
}
impl From<$from> for [u8; $size] {
fn from(s: $from) -> Self {
s.0
}
}
impl Deref for $from {
type Target = [u8];
@ -409,9 +415,9 @@ impl<'a> From<&'a H256> for U256 {
}
}
impl From<H256> for Address {
fn from(value: H256) -> Address {
let mut ret = Address::new();
impl From<H256> for H160 {
fn from(value: H256) -> H160 {
let mut ret = H160::new();
ret.0.copy_from_slice(&value[12..32]);
ret
}
@ -425,16 +431,16 @@ impl From<H256> for H64 {
}
}
impl From<Address> for H256 {
fn from(value: Address) -> H256 {
impl From<H160> for H256 {
fn from(value: H160) -> H256 {
let mut ret = H256::new();
ret.0[12..32].copy_from_slice(&value);
ret
}
}
impl<'a> From<&'a Address> for H256 {
fn from(value: &'a Address) -> H256 {
impl<'a> From<&'a H160> for H256 {
fn from(value: &'a H160) -> H256 {
let mut ret = H256::new();
ret.0[12..32].copy_from_slice(value);
ret
@ -444,7 +450,7 @@ impl<'a> From<&'a Address> for H256 {
impl_hash!(H32, 4);
impl_hash!(H64, 8);
impl_hash!(H128, 16);
impl_hash!(Address, 20);
impl_hash!(H160, 20);
impl_hash!(H256, 32);
impl_hash!(H264, 33);
impl_hash!(H512, 64);
@ -452,7 +458,7 @@ impl_hash!(H520, 65);
impl_hash!(H1024, 128);
impl_hash!(H2048, 256);
known_heap_size!(0, H32, H64, H128, Address, H256, H264, H512, H520, H1024, H2048);
known_heap_size!(0, H32, H64, H128, H160, H256, H264, H512, H520, H1024, H2048);
// Specialized HashMap and HashSet
/// Hasher that just takes 8 bytes of the provided value.
@ -535,9 +541,9 @@ mod tests {
#[test]
fn from_and_to_address() {
let address = Address::from_str("ef2d6d194084c2de36e0dabfce45d046b37d1106").unwrap();
let address: H160 = "ef2d6d194084c2de36e0dabfce45d046b37d1106".into();
let h = H256::from(address.clone());
let a = Address::from(h);
let a = H160::from(h);
assert_eq!(address, a);
}

View File

@ -36,14 +36,11 @@
//! The functions here are designed to be fast.
//!
use std::mem;
use std::fmt;
use std::{mem, fmt};
use std::str::{FromStr};
use std::convert::From;
use std::hash::Hash;
use std::ops::*;
use std::cmp::*;
use std::ops::{Shr, Shl, BitAnd, BitOr, BitXor, Not, Div, Rem, Mul, Add, Sub};
use std::cmp::Ordering;
use rustc_serialize::hex::{FromHex, FromHexError};
/// Conversion from decimal string error
@ -2208,5 +2205,59 @@ mod tests {
let result = U256([1, 2, 3, 4]).full_mul(U256([5, 6, 7, 8]));
assert_eq!(U512([5, 16, 34, 60, 61, 52, 32, 0]), result);
}
}
#[test]
fn u256_multi_muls2() {
let (result, _) = U256([0, 0, 0, 0]).overflowing_mul(U256([0, 0, 0, 0]));
assert_eq!(U256([0, 0, 0, 0]), result);
let (result, _) = U256([1, 0, 0, 0]).overflowing_mul(U256([1, 0, 0, 0]));
assert_eq!(U256([1, 0, 0, 0]), result);
let (result, _) = U256([5, 0, 0, 0]).overflowing_mul(U256([5, 0, 0, 0]));
assert_eq!(U256([25, 0, 0, 0]), result);
let (result, _) = U256([0, 5, 0, 0]).overflowing_mul(U256([0, 5, 0, 0]));
assert_eq!(U256([0, 0, 25, 0]), result);
let (result, _) = U256([0, 0, 0, 1]).overflowing_mul(U256([1, 0, 0, 0]));
assert_eq!(U256([0, 0, 0, 1]), result);
let (result, _) = U256([0, 0, 0, 5]).overflowing_mul(U256([2, 0, 0, 0]));
assert_eq!(U256([0, 0, 0, 10]), result);
let (result, _) = U256([0, 0, 1, 0]).overflowing_mul(U256([0, 5, 0, 0]));
assert_eq!(U256([0, 0, 0, 5]), result);
let (result, _) = U256([0, 0, 8, 0]).overflowing_mul(U256([0, 0, 7, 0]));
assert_eq!(U256([0, 0, 0, 0]), result);
let (result, _) = U256([2, 0, 0, 0]).overflowing_mul(U256([0, 5, 0, 0]));
assert_eq!(U256([0, 10, 0, 0]), result);
let (result, _) = U256([1, 0, 0, 0]).overflowing_mul(U256([0, 0, 0, u64::max_value()]));
assert_eq!(U256([0, 0, 0, u64::max_value()]), result);
let x1: U256 = "0000000000000000000000000000000000000000000000000000012365124623".into();
let x2sqr_right: U256 = "000000000000000000000000000000000000000000014baeef72e0378e2328c9".into();
let x1sqr = x1 * x1;
assert_eq!(x2sqr_right, x1sqr);
let x1cube = x1sqr * x1;
let x1cube_right: U256 = "0000000000000000000000000000000001798acde139361466f712813717897b".into();
assert_eq!(x1cube_right, x1cube);
let x1quad = x1cube * x1;
let x1quad_right: U256 = "000000000000000000000001adbdd6bd6ff027485484b97f8a6a4c7129756dd1".into();
assert_eq!(x1quad_right, x1quad);
let x1penta = x1quad * x1;
let x1penta_right: U256 = "00000000000001e92875ac24be246e1c57e0507e8c46cc8d233b77f6f4c72993".into();
assert_eq!(x1penta_right, x1penta);
let x1septima = x1penta * x1;
let x1septima_right: U256 = "00022cca1da3f6e5722b7d3cc5bbfb486465ebc5a708dd293042f932d7eee119".into();
assert_eq!(x1septima_right, x1septima);
}
}

View File

@ -18,7 +18,7 @@
use std::mem;
use std::ops::DerefMut;
use {H64, Address, H256, H512, H520, H2048, FixedHash};
use {H64, H160, H256, H512, H520, H2048, FixedHash};
/// Returns log2.
pub fn log2(x: usize) -> u32 {
@ -110,7 +110,7 @@ macro_rules! impl_bloomable_for_hash {
}
impl_bloomable_for_hash!(H64, 8);
impl_bloomable_for_hash!(Address, 20);
impl_bloomable_for_hash!(H160, 20);
impl_bloomable_for_hash!(H256, 32);
impl_bloomable_for_hash!(H512, 64);
impl_bloomable_for_hash!(H520, 65);
@ -118,14 +118,14 @@ impl_bloomable_for_hash!(H2048, 256);
#[cfg(test)]
mod tests {
use {Address, H256, H2048};
use {H160, H256, H2048};
use sha3::Hashable;
use super::Bloomable;
#[test]
fn shift_bloomed() {
let bloom: H2048 = "00000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020000000000000000000000000000000000000000000008000000001000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".into();
let address: Address = "ef2d6d194084c2de36e0dabfce45d046b37d1106".into();
let address: H160 = "ef2d6d194084c2de36e0dabfce45d046b37d1106".into();
let topic: H256 = "02c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc".into();
let mut my_bloom = H2048::default();

View File

@ -232,7 +232,7 @@ fn fax_raw_dyn() {
#[test]
fn populate_big_types() {
use hash::*;
let a: Address = "ffffffffffffffffffffffffffffffffffffffff".into();
let a: H160 = "ffffffffffffffffffffffffffffffffffffffff".into();
let mut h: H256 = 0x69.into();
h.populate_raw_from(&a);
assert_eq!(h, "ffffffffffffffffffffffffffffffffffffffff000000000000000000000000".into());

View File

@ -23,6 +23,7 @@ use secp256k1::{key, Secp256k1};
use rand::os::OsRng;
use sha3::Hashable;
use std::fmt;
use Address;
/// Secret key for secp256k1 EC operations. 256 bit generic "hash" data.
pub type Secret = H256;

View File

@ -156,59 +156,5 @@ pub use log::*;
pub use kvdb::*;
pub use timer::*;
#[cfg(test)]
mod tests {
use std::str::FromStr;
use {U256, H256, Uint};
pub type Address = H160;
#[test]
fn u256_multi_muls() {
let (result, _) = U256([0, 0, 0, 0]).overflowing_mul(U256([0, 0, 0, 0]));
assert_eq!(U256([0, 0, 0, 0]), result);
let (result, _) = U256([1, 0, 0, 0]).overflowing_mul(U256([1, 0, 0, 0]));
assert_eq!(U256([1, 0, 0, 0]), result);
let (result, _) = U256([5, 0, 0, 0]).overflowing_mul(U256([5, 0, 0, 0]));
assert_eq!(U256([25, 0, 0, 0]), result);
let (result, _) = U256([0, 5, 0, 0]).overflowing_mul(U256([0, 5, 0, 0]));
assert_eq!(U256([0, 0, 25, 0]), result);
let (result, _) = U256([0, 0, 0, 1]).overflowing_mul(U256([1, 0, 0, 0]));
assert_eq!(U256([0, 0, 0, 1]), result);
let (result, _) = U256([0, 0, 0, 5]).overflowing_mul(U256([2, 0, 0, 0]));
assert_eq!(U256([0, 0, 0, 10]), result);
let (result, _) = U256([0, 0, 1, 0]).overflowing_mul(U256([0, 5, 0, 0]));
assert_eq!(U256([0, 0, 0, 5]), result);
let (result, _) = U256([0, 0, 8, 0]).overflowing_mul(U256([0, 0, 7, 0]));
assert_eq!(U256([0, 0, 0, 0]), result);
let (result, _) = U256([2, 0, 0, 0]).overflowing_mul(U256([0, 5, 0, 0]));
assert_eq!(U256([0, 10, 0, 0]), result);
let (result, _) = U256([1, 0, 0, 0]).overflowing_mul(U256([0, 0, 0, ::std::u64::MAX]));
assert_eq!(U256([0, 0, 0, ::std::u64::MAX]), result);
let x1 = U256::from_str("0000000000000000000000000000000000000000000000000000012365124623").unwrap();
let x2sqr_right = U256::from_str("000000000000000000000000000000000000000000014baeef72e0378e2328c9").unwrap();
let x1sqr = x1 * x1;
assert_eq!(H256::from(x2sqr_right), H256::from(x1sqr));
let x1cube = x1sqr * x1;
let x1cube_right = U256::from_str("0000000000000000000000000000000001798acde139361466f712813717897b").unwrap();
assert_eq!(H256::from(x1cube_right), H256::from(x1cube));
let x1quad = x1cube * x1;
let x1quad_right = U256::from_str("000000000000000000000001adbdd6bd6ff027485484b97f8a6a4c7129756dd1").unwrap();
assert_eq!(H256::from(x1quad_right), H256::from(x1quad));
let x1penta = x1quad * x1;
let x1penta_right = U256::from_str("00000000000001e92875ac24be246e1c57e0507e8c46cc8d233b77f6f4c72993").unwrap();
assert_eq!(H256::from(x1penta_right), H256::from(x1penta));
let x1septima = x1penta * x1;
let x1septima_right = U256::from_str("00022cca1da3f6e5722b7d3cc5bbfb486465ebc5a708dd293042f932d7eee119").unwrap();
assert_eq!(H256::from(x1septima_right), H256::from(x1septima));
}
}

View File

@ -22,7 +22,7 @@ use std::fmt;
use std::cmp::Ordering;
use std::error::Error as StdError;
use bigint::uint::{Uint, U128, U256};
use hash::{H64, H128, Address, H256, H512, H520, H2048};
use hash::{H64, H128, H160, H256, H512, H520, H2048};
use elastic_array::*;
/// Vector like object
@ -159,7 +159,7 @@ macro_rules! impl_hash_to_bytes {
impl_hash_to_bytes!(H64);
impl_hash_to_bytes!(H128);
impl_hash_to_bytes!(Address);
impl_hash_to_bytes!(H160);
impl_hash_to_bytes!(H256);
impl_hash_to_bytes!(H512);
impl_hash_to_bytes!(H520);
@ -282,7 +282,7 @@ macro_rules! impl_hash_from_bytes {
impl_hash_from_bytes!(H64, 8);
impl_hash_from_bytes!(H128, 16);
impl_hash_from_bytes!(Address, 20);
impl_hash_from_bytes!(H160, 20);
impl_hash_from_bytes!(H256, 32);
impl_hash_from_bytes!(H512, 64);
impl_hash_from_bytes!(H520, 65);

View File

@ -168,7 +168,7 @@ fn encode_address() {
use hash::*;
let tests = vec![
ETestPair(Address::from_str("ef2d6d194084c2de36e0dabfce45d046b37d1106").unwrap(),
ETestPair(H160::from("ef2d6d194084c2de36e0dabfce45d046b37d1106"),
vec![0x94, 0xef, 0x2d, 0x6d, 0x19, 0x40, 0x84, 0xc2, 0xde,
0x36, 0xe0, 0xda, 0xbf, 0xce, 0x45, 0xd0, 0x46,
0xb3, 0x7d, 0x11, 0x06])
@ -304,7 +304,7 @@ fn decode_untrusted_address() {
use hash::*;
let tests = vec![
DTestPair(Address::from_str("ef2d6d194084c2de36e0dabfce45d046b37d1106").unwrap(),
DTestPair(H160::from("ef2d6d194084c2de36e0dabfce45d046b37d1106"),
vec![0x94, 0xef, 0x2d, 0x6d, 0x19, 0x40, 0x84, 0xc2, 0xde,
0x36, 0xe0, 0xda, 0xbf, 0xce, 0x45, 0xd0, 0x46,
0xb3, 0x7d, 0x11, 0x06])