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:
parent
e6d9fb2ad3
commit
c39761c042
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -494,6 +494,7 @@ dependencies = [
|
|||||||
name = "ethkey"
|
name = "ethkey"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bigint 0.1.0",
|
||||||
"eth-secp256k1 0.5.4 (git+https://github.com/ethcore/rust-secp256k1)",
|
"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)",
|
"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)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -18,13 +18,14 @@
|
|||||||
|
|
||||||
use std::{fs, fmt};
|
use std::{fs, fmt};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::time::{Instant, Duration};
|
|
||||||
use util::{Address as H160, H256, H520, Mutex, RwLock};
|
|
||||||
use std::path::PathBuf;
|
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::{SecretStore, Error as SSError, SafeAccount, EthStore};
|
||||||
use ethstore::dir::{KeyDirectory};
|
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.
|
/// Type of unlock.
|
||||||
#[derive(Clone)]
|
#[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)]
|
#[derive(Default)]
|
||||||
struct NullDir {
|
struct NullDir {
|
||||||
accounts: RwLock<HashMap<SSAddress, SafeAccount>>,
|
accounts: RwLock<HashMap<Address, SafeAccount>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KeyDirectory for NullDir {
|
impl KeyDirectory for NullDir {
|
||||||
@ -126,7 +85,7 @@ impl KeyDirectory for NullDir {
|
|||||||
Ok(account)
|
Ok(account)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove(&self, address: &SSAddress) -> Result<(), SSError> {
|
fn remove(&self, address: &Address) -> Result<(), SSError> {
|
||||||
self.accounts.write().remove(address);
|
self.accounts.write().remove(address);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -135,7 +94,7 @@ impl KeyDirectory for NullDir {
|
|||||||
/// Disk-backed map from Address to String. Uses JSON.
|
/// Disk-backed map from Address to String. Uses JSON.
|
||||||
struct AddressBook {
|
struct AddressBook {
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
cache: HashMap<H160, AccountMeta>,
|
cache: HashMap<Address, AccountMeta>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AddressBook {
|
impl AddressBook {
|
||||||
@ -152,23 +111,23 @@ impl AddressBook {
|
|||||||
r
|
r
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get(&self) -> HashMap<H160, AccountMeta> {
|
pub fn get(&self) -> HashMap<Address, AccountMeta> {
|
||||||
self.cache.clone()
|
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)
|
let mut x = self.cache.get(&a)
|
||||||
.map(|a| a.clone())
|
.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;
|
x.name = name;
|
||||||
self.cache.insert(a, x);
|
self.cache.insert(a, x);
|
||||||
self.save();
|
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)
|
let mut x = self.cache.get(&a)
|
||||||
.map(|a| a.clone())
|
.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;
|
x.meta = meta;
|
||||||
self.cache.insert(a, x);
|
self.cache.insert(a, x);
|
||||||
self.save();
|
self.save();
|
||||||
@ -197,7 +156,7 @@ impl AddressBook {
|
|||||||
/// Account management.
|
/// Account management.
|
||||||
/// Responsible for unlocking accounts.
|
/// Responsible for unlocking accounts.
|
||||||
pub struct AccountProvider {
|
pub struct AccountProvider {
|
||||||
unlocked: Mutex<HashMap<SSAddress, AccountData>>,
|
unlocked: Mutex<HashMap<Address, AccountData>>,
|
||||||
sstore: Box<SecretStore>,
|
sstore: Box<SecretStore>,
|
||||||
address_book: Mutex<AddressBook>,
|
address_book: Mutex<AddressBook>,
|
||||||
}
|
}
|
||||||
@ -222,67 +181,63 @@ impl AccountProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates new random account.
|
/// 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 secret = Random.generate().unwrap().secret().clone();
|
||||||
let address = try!(self.sstore.insert_account(secret, password));
|
let address = try!(self.sstore.insert_account(secret, password));
|
||||||
Ok(Address::from(address).into())
|
Ok(address)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Inserts new account into underlying store.
|
/// Inserts new account into underlying store.
|
||||||
/// Does not unlock account!
|
/// Does not unlock account!
|
||||||
pub fn insert_account<S>(&self, secret: S, password: &str) -> Result<H160, Error> where Secret: From<S> {
|
pub fn insert_account(&self, secret: Secret, password: &str) -> Result<Address, Error> {
|
||||||
let s = Secret::from(secret);
|
let address = try!(self.sstore.insert_account(secret, password));
|
||||||
let address = try!(self.sstore.insert_account(s.into(), password));
|
Ok(address)
|
||||||
Ok(Address::from(address).into())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Import a new presale wallet.
|
/// 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));
|
let address = try!(self.sstore.import_presale(presale_json, password));
|
||||||
Ok(Address::from(address).into())
|
Ok(Address::from(address).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Import a new presale wallet.
|
/// 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));
|
let address = try!(self.sstore.import_wallet(json, password));
|
||||||
Ok(Address::from(address).into())
|
Ok(Address::from(address).into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns addresses of all accounts.
|
/// Returns addresses of all accounts.
|
||||||
pub fn accounts(&self) -> Result<Vec<H160>, Error> {
|
pub fn accounts(&self) -> Result<Vec<Address>, Error> {
|
||||||
let accounts = try!(self.sstore.accounts()).into_iter().map(|a| H160(a.into())).collect();
|
let accounts = try!(self.sstore.accounts());
|
||||||
Ok(accounts)
|
Ok(accounts)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns each address along with metadata.
|
/// 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())
|
Ok(self.address_book.lock().get())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns each address along with metadata.
|
/// Returns each address along with metadata.
|
||||||
pub fn set_address_name<A>(&self, account: A, name: String) -> Result<(), Error> where Address: From<A> {
|
pub fn set_address_name(&self, account: Address, name: String) -> Result<(), Error> {
|
||||||
let account = Address::from(account).into();
|
|
||||||
Ok(self.address_book.lock().set_name(account, name))
|
Ok(self.address_book.lock().set_name(account, name))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns each address along with metadata.
|
/// Returns each address along with metadata.
|
||||||
pub fn set_address_meta<A>(&self, account: A, meta: String) -> Result<(), Error> where Address: From<A> {
|
pub fn set_address_meta(&self, account: Address, meta: String) -> Result<(), Error> {
|
||||||
let account = Address::from(account).into();
|
|
||||||
Ok(self.address_book.lock().set_meta(account, meta))
|
Ok(self.address_book.lock().set_meta(account, meta))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns each account along with name and meta.
|
/// Returns each account along with name and meta.
|
||||||
pub fn accounts_info(&self) -> Result<HashMap<H160, AccountMeta>, Error> {
|
pub fn accounts_info(&self) -> Result<HashMap<Address, AccountMeta>, Error> {
|
||||||
let r: HashMap<H160, AccountMeta> = try!(self.sstore.accounts())
|
let r: HashMap<Address, AccountMeta> = try!(self.sstore.accounts())
|
||||||
.into_iter()
|
.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();
|
.collect();
|
||||||
Ok(r)
|
Ok(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns each account along with name and meta.
|
/// Returns each account along with name and meta.
|
||||||
pub fn account_meta<A>(&self, account: A) -> Result<AccountMeta, Error> where Address: From<A> {
|
pub fn account_meta(&self, account: Address) -> Result<AccountMeta, Error> {
|
||||||
let account = Address::from(account).into();
|
|
||||||
Ok(AccountMeta {
|
Ok(AccountMeta {
|
||||||
name: try!(self.sstore.name(&account)),
|
name: try!(self.sstore.name(&account)),
|
||||||
meta: try!(self.sstore.meta(&account)),
|
meta: try!(self.sstore.meta(&account)),
|
||||||
@ -291,23 +246,19 @@ impl AccountProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns each account along with name and meta.
|
/// 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> {
|
pub fn set_account_name(&self, account: Address, name: String) -> Result<(), Error> {
|
||||||
let account = Address::from(account).into();
|
|
||||||
try!(self.sstore.set_name(&account, name));
|
try!(self.sstore.set_name(&account, name));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns each account along with name and meta.
|
/// 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> {
|
pub fn set_account_meta(&self, account: Address, meta: String) -> Result<(), Error> {
|
||||||
let account = Address::from(account).into();
|
|
||||||
try!(self.sstore.set_meta(&account, meta));
|
try!(self.sstore.set_meta(&account, meta));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper method used for unlocking accounts.
|
/// Helper method used for unlocking accounts.
|
||||||
fn unlock_account<A>(&self, account: A, password: String, unlock: Unlock) -> Result<(), Error> where Address: From<A> {
|
fn unlock_account(&self, account: Address, password: String, unlock: Unlock) -> Result<(), Error> {
|
||||||
let a = Address::from(account);
|
|
||||||
let account = a.into();
|
|
||||||
// verify password by signing dump message
|
// verify password by signing dump message
|
||||||
// result may be discarded
|
// result may be discarded
|
||||||
let _ = try!(self.sstore.sign(&account, &password, &Default::default()));
|
let _ = try!(self.sstore.sign(&account, &password, &Default::default()));
|
||||||
@ -330,32 +281,28 @@ impl AccountProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Unlocks account permanently.
|
/// 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)
|
self.unlock_account(account, password, Unlock::Perm)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Unlocks account temporarily (for one signing).
|
/// 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)
|
self.unlock_account(account, password, Unlock::Temp)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Unlocks account temporarily with a timeout.
|
/// 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)))
|
self.unlock_account(account, password, Unlock::Timed((Instant::now(), duration_ms)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if given account is unlocked
|
/// Checks if given account is unlocked
|
||||||
pub fn is_unlocked<A>(&self, account: A) -> bool where Address: From<A> {
|
pub fn is_unlocked(&self, account: Address) -> bool {
|
||||||
let account = Address::from(account).into();
|
|
||||||
let unlocked = self.unlocked.lock();
|
let unlocked = self.unlocked.lock();
|
||||||
unlocked.get(&account).is_some()
|
unlocked.get(&account).is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Signs the message. Account must be unlocked.
|
/// 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> {
|
pub fn sign(&self, account: Address, message: Message) -> Result<Signature, Error> {
|
||||||
let account = Address::from(account).into();
|
|
||||||
let message = Message::from(message).into();
|
|
||||||
|
|
||||||
let data = {
|
let data = {
|
||||||
let mut unlocked = self.unlocked.lock();
|
let mut unlocked = self.unlocked.lock();
|
||||||
let data = try!(unlocked.get(&account).ok_or(Error::NotUnlocked)).clone();
|
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));
|
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.
|
/// 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> {
|
pub fn sign_with_password(&self, account: Address, password: String, message: Message) -> Result<Signature, Error> {
|
||||||
let account = Address::from(account).into();
|
|
||||||
let message = Message::from(message).into();
|
|
||||||
let signature = try!(self.sstore.sign(&account, &password, &message));
|
let signature = try!(self.sstore.sign(&account, &password, &message));
|
||||||
Ok(H520(signature.into()))
|
Ok(signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the underlying `SecretStore` reference if one exists.
|
/// 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()
|
self.sstore.list_geth_accounts(testnet).into_iter().map(|a| Address::from(a).into()).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the underlying `SecretStore` reference if one exists.
|
/// Returns the underlying `SecretStore` reference if one exists.
|
||||||
pub fn import_geth_accounts(&self, desired: Vec<H160>, testnet: bool) -> Result<Vec<H160>, Error> {
|
pub fn import_geth_accounts(&self, desired: Vec<Address>, testnet: bool) -> Result<Vec<Address>, Error> {
|
||||||
let desired = desired.into_iter().map(|a| Address::from(a).into()).collect();
|
self.sstore.import_geth_accounts(desired, testnet).map_err(Into::into)
|
||||||
Ok(try!(self.sstore.import_geth_accounts(desired, testnet)).into_iter().map(|a| Address::from(a).into()).collect())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,8 +366,8 @@ mod tests {
|
|||||||
assert!(ap.insert_account(kp.secret().clone(), "test").is_ok());
|
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(), "test1".into()).is_err());
|
||||||
assert!(ap.unlock_account_temporarily(kp.address(), "test".into()).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(), Default::default()).is_ok());
|
||||||
assert!(ap.sign(kp.address(), [0u8; 32]).is_err());
|
assert!(ap.sign(kp.address(), Default::default()).is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -433,11 +377,11 @@ mod tests {
|
|||||||
assert!(ap.insert_account(kp.secret().clone(), "test").is_ok());
|
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(), "test1".into()).is_err());
|
||||||
assert!(ap.unlock_account_permanently(kp.address(), "test".into()).is_ok());
|
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(), Default::default()).is_ok());
|
||||||
assert!(ap.sign(kp.address(), [0u8; 32]).is_ok());
|
assert!(ap.sign(kp.address(), Default::default()).is_ok());
|
||||||
assert!(ap.unlock_account_temporarily(kp.address(), "test".into()).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(), Default::default()).is_ok());
|
||||||
assert!(ap.sign(kp.address(), [0u8; 32]).is_ok());
|
assert!(ap.sign(kp.address(), Default::default()).is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -447,8 +391,8 @@ mod tests {
|
|||||||
assert!(ap.insert_account(kp.secret().clone(), "test").is_ok());
|
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(), "test1".into(), 2000).is_err());
|
||||||
assert!(ap.unlock_account_timed(kp.address(), "test".into(), 2000).is_ok());
|
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));
|
::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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ impl Engine for BasicAuthority {
|
|||||||
let message = header.bare_hash();
|
let message = header.bare_hash();
|
||||||
// account should be pernamently unlocked, otherwise sealing will fail
|
// account should be pernamently unlocked, otherwise sealing will fail
|
||||||
if let Ok(signature) = ap.sign(*block.header().author(), message) {
|
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 {
|
} else {
|
||||||
trace!(target: "basicauthority", "generate_seal: FAIL: accounts secret key unavailable");
|
trace!(target: "basicauthority", "generate_seal: FAIL: accounts secret key unavailable");
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use util::hash::Address;
|
use util::Address;
|
||||||
use builtin::Builtin;
|
use builtin::Builtin;
|
||||||
use engines::Engine;
|
use engines::Engine;
|
||||||
use spec::CommonParams;
|
use spec::CommonParams;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use util::hash::Address;
|
use util::Address;
|
||||||
use builtin::Builtin;
|
use builtin::Builtin;
|
||||||
use engines::Engine;
|
use engines::Engine;
|
||||||
use spec::CommonParams;
|
use spec::CommonParams;
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
//! Interface for Evm externalities.
|
//! Interface for Evm externalities.
|
||||||
|
|
||||||
use util::common::*;
|
use util::*;
|
||||||
use evm::{self, Schedule};
|
use evm::{self, Schedule};
|
||||||
use env_info::*;
|
use env_info::*;
|
||||||
use types::executed::CallType;
|
use types::executed::CallType;
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use util::Bytes;
|
use util::Bytes;
|
||||||
use util::hash::{Address, FixedHash, H256};
|
use util::{Address, FixedHash, H256};
|
||||||
use util::kvdb::Database;
|
use util::kvdb::Database;
|
||||||
use util::migration::{Batch, Config, Error, Migration, SimpleMigration, Progress};
|
use util::migration::{Batch, Config, Error, Migration, SimpleMigration, Progress};
|
||||||
use util::rlp::{decode, Rlp, RlpStream, Stream, View};
|
use util::rlp::{decode, Rlp, RlpStream, Stream, View};
|
||||||
|
@ -144,7 +144,7 @@ mod tests {
|
|||||||
use snapshot::tests::helpers::fill_storage;
|
use snapshot::tests::helpers::fill_storage;
|
||||||
|
|
||||||
use util::{SHA3_NULL_RLP, SHA3_EMPTY};
|
use util::{SHA3_NULL_RLP, SHA3_EMPTY};
|
||||||
use util::hash::{Address, FixedHash, H256};
|
use util::{Address, FixedHash, H256};
|
||||||
use util::rlp::{UntrustedRlp, View};
|
use util::rlp::{UntrustedRlp, View};
|
||||||
|
|
||||||
use super::Account;
|
use super::Account;
|
||||||
|
@ -422,8 +422,10 @@ impl Clone for State {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
|
use std::str::FromStr;
|
||||||
|
use rustc_serialize::hex::FromHex;
|
||||||
use super::*;
|
use super::*;
|
||||||
use util::common::*;
|
use util::{U256, H256, FixedHash, Address, Hashable};
|
||||||
use account::*;
|
use account::*;
|
||||||
use tests::helpers::*;
|
use tests::helpers::*;
|
||||||
use devtools::*;
|
use devtools::*;
|
||||||
|
@ -16,14 +16,13 @@
|
|||||||
|
|
||||||
//! Blockchain filter
|
//! Blockchain filter
|
||||||
|
|
||||||
use util::hash::*;
|
use std::mem;
|
||||||
use util::sha3::*;
|
use std::collections::VecDeque;
|
||||||
|
use util::{Address, H256, Hashable, H2048};
|
||||||
use util::bloom::Bloomable;
|
use util::bloom::Bloomable;
|
||||||
use client::BlockID;
|
use client::BlockID;
|
||||||
use log_entry::LogEntry;
|
use log_entry::LogEntry;
|
||||||
use ipc::binary::BinaryConvertError;
|
use ipc::binary::BinaryConvertError;
|
||||||
use std::mem;
|
|
||||||
use std::collections::VecDeque;
|
|
||||||
|
|
||||||
/// Blockchain Filter.
|
/// Blockchain Filter.
|
||||||
#[derive(Binary)]
|
#[derive(Binary)]
|
||||||
@ -74,11 +73,11 @@ impl Filter {
|
|||||||
let blooms = match self.address {
|
let blooms = match self.address {
|
||||||
Some(ref addresses) if !addresses.is_empty() =>
|
Some(ref addresses) if !addresses.is_empty() =>
|
||||||
addresses.iter().map(|ref address| {
|
addresses.iter().map(|ref address| {
|
||||||
let mut bloom = H2048::new();
|
let mut bloom = H2048::default();
|
||||||
bloom.shift_bloomed(&address.sha3());
|
bloom.shift_bloomed(&address.sha3());
|
||||||
bloom
|
bloom
|
||||||
}).collect(),
|
}).collect(),
|
||||||
_ => vec![H2048::new()]
|
_ => vec![H2048::default()]
|
||||||
};
|
};
|
||||||
|
|
||||||
self.topics.iter().fold(blooms, |bs, topic| match *topic {
|
self.topics.iter().fold(blooms, |bs, topic| match *topic {
|
||||||
@ -109,8 +108,7 @@ impl Filter {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::str::FromStr;
|
use util::FixedHash;
|
||||||
use util::hash::*;
|
|
||||||
use filter::Filter;
|
use filter::Filter;
|
||||||
use client::BlockID;
|
use client::BlockID;
|
||||||
use log_entry::LogEntry;
|
use log_entry::LogEntry;
|
||||||
@ -135,9 +133,9 @@ mod tests {
|
|||||||
let filter = Filter {
|
let filter = Filter {
|
||||||
from_block: BlockID::Earliest,
|
from_block: BlockID::Earliest,
|
||||||
to_block: BlockID::Latest,
|
to_block: BlockID::Latest,
|
||||||
address: Some(vec![Address::from_str("b372018f3be9e171df0581136b59d2faf73a7d5d").unwrap()]),
|
address: Some(vec!["b372018f3be9e171df0581136b59d2faf73a7d5d".into()]),
|
||||||
topics: vec![
|
topics: vec![
|
||||||
Some(vec![H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap()]),
|
Some(vec!["ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9".into()]),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
@ -145,7 +143,7 @@ mod tests {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let possibilities = filter.bloom_possibilities();
|
let possibilities = filter.bloom_possibilities();
|
||||||
assert_eq!(possibilities, vec![H2048::from_str("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000004000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000").unwrap()]);
|
assert_eq!(possibilities, vec!["00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000004000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000".into()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -153,17 +151,17 @@ mod tests {
|
|||||||
let filter = Filter {
|
let filter = Filter {
|
||||||
from_block: BlockID::Earliest,
|
from_block: BlockID::Earliest,
|
||||||
to_block: BlockID::Latest,
|
to_block: BlockID::Latest,
|
||||||
address: Some(vec![Address::from_str("b372018f3be9e171df0581136b59d2faf73a7d5d").unwrap()]),
|
address: Some(vec!["b372018f3be9e171df0581136b59d2faf73a7d5d".into()]),
|
||||||
topics: vec![
|
topics: vec![
|
||||||
Some(vec![H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap()]),
|
Some(vec!["ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9".into()]),
|
||||||
Some(vec![H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap()]),
|
Some(vec!["ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9".into()]),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
let possibilities = filter.bloom_possibilities();
|
let possibilities = filter.bloom_possibilities();
|
||||||
assert_eq!(possibilities, vec![H2048::from_str("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000004000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000").unwrap()]);
|
assert_eq!(possibilities, vec!["00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000004000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000".into()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -172,19 +170,19 @@ mod tests {
|
|||||||
from_block: BlockID::Earliest,
|
from_block: BlockID::Earliest,
|
||||||
to_block: BlockID::Latest,
|
to_block: BlockID::Latest,
|
||||||
address: Some(vec![
|
address: Some(vec![
|
||||||
Address::from_str("b372018f3be9e171df0581136b59d2faf73a7d5d").unwrap(),
|
"b372018f3be9e171df0581136b59d2faf73a7d5d".into(),
|
||||||
Address::from_str("b372018f3be9e171df0581136b59d2faf73a7d5d").unwrap(),
|
"b372018f3be9e171df0581136b59d2faf73a7d5d".into(),
|
||||||
]),
|
]),
|
||||||
topics: vec![
|
topics: vec![
|
||||||
Some(vec![
|
Some(vec![
|
||||||
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap(),
|
"ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9".into(),
|
||||||
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap()
|
"ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9".into()
|
||||||
]),
|
]),
|
||||||
Some(vec![
|
Some(vec![
|
||||||
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap(),
|
"ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9".into(),
|
||||||
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap()
|
"ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9".into()
|
||||||
]),
|
]),
|
||||||
Some(vec![H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap()]),
|
Some(vec!["ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9".into()]),
|
||||||
None
|
None
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
@ -192,7 +190,7 @@ mod tests {
|
|||||||
// number of possibilites should be equal 2 * 2 * 2 * 1 = 8
|
// number of possibilites should be equal 2 * 2 * 2 * 1 = 8
|
||||||
let possibilities = filter.bloom_possibilities();
|
let possibilities = filter.bloom_possibilities();
|
||||||
assert_eq!(possibilities.len(), 8);
|
assert_eq!(possibilities.len(), 8);
|
||||||
assert_eq!(possibilities[0], H2048::from_str("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000004000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000").unwrap());
|
assert_eq!(possibilities[0], "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000004000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000".into());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -200,39 +198,39 @@ mod tests {
|
|||||||
let filter = Filter {
|
let filter = Filter {
|
||||||
from_block: BlockID::Earliest,
|
from_block: BlockID::Earliest,
|
||||||
to_block: BlockID::Latest,
|
to_block: BlockID::Latest,
|
||||||
address: Some(vec![Address::from_str("b372018f3be9e171df0581136b59d2faf73a7d5d").unwrap()]),
|
address: Some(vec!["b372018f3be9e171df0581136b59d2faf73a7d5d".into()]),
|
||||||
topics: vec![
|
topics: vec![
|
||||||
Some(vec![H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap()]),
|
Some(vec!["ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9".into()]),
|
||||||
Some(vec![H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23fa").unwrap()]),
|
Some(vec!["ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23fa".into()]),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
let entry0 = LogEntry {
|
let entry0 = LogEntry {
|
||||||
address: Address::from_str("b372018f3be9e171df0581136b59d2faf73a7d5d").unwrap(),
|
address: "b372018f3be9e171df0581136b59d2faf73a7d5d".into(),
|
||||||
topics: vec![
|
topics: vec![
|
||||||
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap(),
|
"ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9".into(),
|
||||||
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23fa").unwrap(),
|
"ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23fa".into(),
|
||||||
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap(),
|
"ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9".into(),
|
||||||
],
|
],
|
||||||
data: vec![]
|
data: vec![]
|
||||||
};
|
};
|
||||||
|
|
||||||
let entry1 = LogEntry {
|
let entry1 = LogEntry {
|
||||||
address: Address::from_str("b372018f3be9e171df0581136b59d2faf73a7d5e").unwrap(),
|
address: "b372018f3be9e171df0581136b59d2faf73a7d5e".into(),
|
||||||
topics: vec![
|
topics: vec![
|
||||||
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap(),
|
"ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9".into(),
|
||||||
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23fa").unwrap(),
|
"ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23fa".into(),
|
||||||
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap(),
|
"ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9".into(),
|
||||||
],
|
],
|
||||||
data: vec![]
|
data: vec![]
|
||||||
};
|
};
|
||||||
|
|
||||||
let entry2 = LogEntry {
|
let entry2 = LogEntry {
|
||||||
address: Address::from_str("b372018f3be9e171df0581136b59d2faf73a7d5d").unwrap(),
|
address: "b372018f3be9e171df0581136b59d2faf73a7d5d".into(),
|
||||||
topics: vec![
|
topics: vec![
|
||||||
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap(),
|
"ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9".into(),
|
||||||
],
|
],
|
||||||
data: vec![]
|
data: vec![]
|
||||||
};
|
};
|
||||||
|
@ -30,6 +30,7 @@ use evm::Schedule;
|
|||||||
use header::BlockNumber;
|
use header::BlockNumber;
|
||||||
use ethjson;
|
use ethjson;
|
||||||
use ipc::binary::BinaryConvertError;
|
use ipc::binary::BinaryConvertError;
|
||||||
|
use ethstore::ethkey::Signature as EthkeySignature;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Binary)]
|
#[derive(Debug, Clone, PartialEq, Eq, Binary)]
|
||||||
/// Transaction action type.
|
/// Transaction action type.
|
||||||
@ -142,11 +143,12 @@ impl Transaction {
|
|||||||
/// Signs the transaction as coming from `sender`.
|
/// Signs the transaction as coming from `sender`.
|
||||||
pub fn sign(self, secret: &Secret) -> SignedTransaction {
|
pub fn sign(self, secret: &Secret) -> SignedTransaction {
|
||||||
let sig = ec::sign(secret, &self.hash()).unwrap();
|
let sig = ec::sign(secret, &self.hash()).unwrap();
|
||||||
self.with_signature(sig)
|
self.with_signature(sig.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Signs the transaction with signature.
|
/// 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);
|
let (r, s, v) = signature_to_rsv(&sig);
|
||||||
SignedTransaction {
|
SignedTransaction {
|
||||||
unsigned: self,
|
unsigned: self,
|
||||||
|
@ -10,6 +10,7 @@ tiny-keccak = "1.0"
|
|||||||
eth-secp256k1 = { git = "https://github.com/ethcore/rust-secp256k1" }
|
eth-secp256k1 = { git = "https://github.com/ethcore/rust-secp256k1" }
|
||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
docopt = { version = "0.6", optional = true }
|
docopt = { version = "0.6", optional = true }
|
||||||
|
bigint = { path = "../util/bigint" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
@ -18,12 +18,11 @@ extern crate docopt;
|
|||||||
extern crate rustc_serialize;
|
extern crate rustc_serialize;
|
||||||
extern crate ethkey;
|
extern crate ethkey;
|
||||||
|
|
||||||
use std::str::FromStr;
|
|
||||||
use std::{env, fmt, process};
|
use std::{env, fmt, process};
|
||||||
use std::num::ParseIntError;
|
use std::num::ParseIntError;
|
||||||
use docopt::Docopt;
|
use docopt::Docopt;
|
||||||
use rustc_serialize::hex::{FromHex, FromHexError};
|
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#"
|
pub const USAGE: &'static str = r#"
|
||||||
Ethereum keys generator.
|
Ethereum keys generator.
|
||||||
@ -148,9 +147,9 @@ fn main() {
|
|||||||
fn display(keypair: KeyPair, mode: DisplayMode) -> String {
|
fn display(keypair: KeyPair, mode: DisplayMode) -> String {
|
||||||
match mode {
|
match mode {
|
||||||
DisplayMode::KeyPair => format!("{}", keypair),
|
DisplayMode::KeyPair => format!("{}", keypair),
|
||||||
DisplayMode::Secret => format!("{}", keypair.secret()),
|
DisplayMode::Secret => format!("{:?}", keypair.secret()),
|
||||||
DisplayMode::Public => format!("{}", keypair.public()),
|
DisplayMode::Public => format!("{:?}", keypair.public()),
|
||||||
DisplayMode::Address => format!("{}", keypair.address()),
|
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 {
|
return if args.cmd_info {
|
||||||
let display_mode = DisplayMode::new(&args);
|
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));
|
let keypair = try!(KeyPair::from_secret(secret));
|
||||||
Ok(display(keypair, display_mode))
|
Ok(display(keypair, display_mode))
|
||||||
} else if args.cmd_generate {
|
} 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))
|
Ok(display(try!(keypair), display_mode))
|
||||||
} else if args.cmd_sign {
|
} else if args.cmd_sign {
|
||||||
let secret = try!(Secret::from_str(&args.arg_secret));
|
let secret = try!(args.arg_secret.parse().map_err(|_| EthkeyError::InvalidSecret));
|
||||||
let message = try!(Message::from_str(&args.arg_message));
|
let message = try!(args.arg_message.parse().map_err(|_| EthkeyError::InvalidMessage));
|
||||||
let signature = try!(sign(&secret, &message));
|
let signature = try!(sign(&secret, &message));
|
||||||
Ok(format!("{}", signature))
|
Ok(format!("{}", signature))
|
||||||
} else if args.cmd_verify {
|
} else if args.cmd_verify {
|
||||||
let signature = try!(Signature::from_str(&args.arg_signature));
|
let signature = try!(args.arg_signature.parse().map_err(|_| EthkeyError::InvalidSignature));
|
||||||
let message = try!(Message::from_str(&args.arg_message));
|
let message = try!(args.arg_message.parse().map_err(|_| EthkeyError::InvalidMessage));
|
||||||
let ok = if args.cmd_public {
|
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))
|
try!(verify_public(&public, &signature, &message))
|
||||||
} else if args.cmd_address {
|
} 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))
|
try!(verify_address(&address, &signature, &message))
|
||||||
} else {
|
} else {
|
||||||
unreachable!();
|
unreachable!();
|
||||||
@ -212,7 +211,7 @@ mod tests {
|
|||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
.collect::<Vec<String>>();
|
.collect::<Vec<String>>();
|
||||||
|
|
||||||
let expected =
|
let expected =
|
||||||
"secret: 17d08f5fe8c77af811caa0c9a187e668ce3b74a99acc3f6d976f075fa8e0be55
|
"secret: 17d08f5fe8c77af811caa0c9a187e668ce3b74a99acc3f6d976f075fa8e0be55
|
||||||
public: 689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124
|
public: 689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124
|
||||||
address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned();
|
address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned();
|
||||||
@ -226,7 +225,7 @@ address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned();
|
|||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
.collect::<Vec<String>>();
|
.collect::<Vec<String>>();
|
||||||
|
|
||||||
let expected =
|
let expected =
|
||||||
"secret: 17d08f5fe8c77af811caa0c9a187e668ce3b74a99acc3f6d976f075fa8e0be55
|
"secret: 17d08f5fe8c77af811caa0c9a187e668ce3b74a99acc3f6d976f075fa8e0be55
|
||||||
public: 689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124
|
public: 689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124
|
||||||
address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned();
|
address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned();
|
||||||
@ -272,7 +271,7 @@ address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned();
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.map(Into::into)
|
.map(Into::into)
|
||||||
.collect::<Vec<String>>();
|
.collect::<Vec<String>>();
|
||||||
|
|
||||||
let expected = "c1878cf60417151c766a712653d26ef350c8c75393458b7a9be715f053215af63dfd3b02c2ae65a8677917a8efa3172acb71cb90196e42106953ea0363c5aaf200".to_owned();
|
let expected = "c1878cf60417151c766a712653d26ef350c8c75393458b7a9be715f053215af63dfd3b02c2ae65a8677917a8efa3172acb71cb90196e42106953ea0363c5aaf200".to_owned();
|
||||||
assert_eq!(execute(command).unwrap(), expected);
|
assert_eq!(execute(command).unwrap(), expected);
|
||||||
}
|
}
|
||||||
|
@ -38,8 +38,8 @@ pub enum Error {
|
|||||||
impl fmt::Display for Error {
|
impl fmt::Display for Error {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let msg = match *self {
|
let msg = match *self {
|
||||||
Error::InvalidSecret => "Invalid secret key".into(),
|
Error::InvalidSecret => "Invalid secret".into(),
|
||||||
Error::InvalidPublic => "Invalid public key".into(),
|
Error::InvalidPublic => "Invalid public".into(),
|
||||||
Error::InvalidAddress => "Invalid address".into(),
|
Error::InvalidAddress => "Invalid address".into(),
|
||||||
Error::InvalidSignature => "Invalid EC signature".into(),
|
Error::InvalidSignature => "Invalid EC signature".into(),
|
||||||
Error::InvalidMessage => "Invalid AES message".into(),
|
Error::InvalidMessage => "Invalid AES message".into(),
|
||||||
|
@ -20,13 +20,13 @@ extern crate lazy_static;
|
|||||||
extern crate tiny_keccak;
|
extern crate tiny_keccak;
|
||||||
extern crate secp256k1;
|
extern crate secp256k1;
|
||||||
extern crate rustc_serialize;
|
extern crate rustc_serialize;
|
||||||
|
extern crate bigint;
|
||||||
|
|
||||||
mod brain;
|
mod brain;
|
||||||
mod error;
|
mod error;
|
||||||
mod keypair;
|
mod keypair;
|
||||||
mod keccak;
|
mod keccak;
|
||||||
mod prefix;
|
mod prefix;
|
||||||
mod primitive;
|
|
||||||
mod random;
|
mod random;
|
||||||
mod signature;
|
mod signature;
|
||||||
|
|
||||||
@ -43,7 +43,13 @@ pub trait Generator {
|
|||||||
pub use self::brain::Brain;
|
pub use self::brain::Brain;
|
||||||
pub use self::error::Error;
|
pub use self::error::Error;
|
||||||
pub use self::keypair::{KeyPair, public_to_address};
|
pub use self::keypair::{KeyPair, public_to_address};
|
||||||
pub use self::primitive::{Secret, Public, Address, Message};
|
|
||||||
pub use self::prefix::Prefix;
|
pub use self::prefix::Prefix;
|
||||||
pub use self::random::Random;
|
pub use self::random::Random;
|
||||||
pub use self::signature::{sign, verify_public, verify_address, recover, Signature};
|
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;
|
||||||
|
@ -14,125 +14,4 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// 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 {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -15,11 +15,13 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
|
use std::cmp::PartialEq;
|
||||||
use std::{mem, fmt};
|
use std::{mem, fmt};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use secp256k1::{Message as SecpMessage, RecoverableSignature, RecoveryId, Error as SecpError};
|
use secp256k1::{Message as SecpMessage, RecoverableSignature, RecoveryId, Error as SecpError};
|
||||||
use secp256k1::key::{SecretKey, PublicKey};
|
use secp256k1::key::{SecretKey, PublicKey};
|
||||||
use rustc_serialize::hex::{ToHex, FromHex};
|
use rustc_serialize::hex::{ToHex, FromHex};
|
||||||
|
use bigint::hash::H520;
|
||||||
use {Secret, Public, SECP256K1, Error, Message, public_to_address, Address};
|
use {Secret, Public, SECP256K1, Error, Message, public_to_address, Address};
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
@ -45,7 +47,7 @@ impl Signature {
|
|||||||
|
|
||||||
// manual implementation large arrays don't have trait impls by default.
|
// manual implementation large arrays don't have trait impls by default.
|
||||||
// remove when integer generics exist
|
// remove when integer generics exist
|
||||||
impl ::std::cmp::PartialEq for Signature {
|
impl PartialEq for Signature {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
&self.0[..] == &other.0[..]
|
&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 {
|
impl Deref for Signature {
|
||||||
type Target = [u8; 65];
|
type Target = [u8; 65];
|
||||||
|
|
||||||
|
@ -21,9 +21,8 @@ extern crate ethstore;
|
|||||||
use std::{env, process, fs};
|
use std::{env, process, fs};
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::str::FromStr;
|
|
||||||
use docopt::Docopt;
|
use docopt::Docopt;
|
||||||
use ethstore::ethkey::{Secret, Address, Message};
|
use ethstore::ethkey::Address;
|
||||||
use ethstore::dir::{KeyDirectory, ParityDirectory, DiskDirectory, GethDirectory, DirectoryType};
|
use ethstore::dir::{KeyDirectory, ParityDirectory, DiskDirectory, GethDirectory, DirectoryType};
|
||||||
use ethstore::{EthStore, SecretStore, import_accounts, Error, PresaleWallet};
|
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))));
|
let store = try!(EthStore::open(try!(key_dir(&args.flag_dir))));
|
||||||
|
|
||||||
return if args.cmd_insert {
|
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 password = try!(load_password(&args.arg_password));
|
||||||
let address = try!(store.insert_account(secret, &password));
|
let address = try!(store.insert_account(secret, &password));
|
||||||
Ok(format!("{}", address))
|
Ok(format!("{}", address))
|
||||||
} else if args.cmd_change_pwd {
|
} 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 old_pwd = try!(load_password(&args.arg_old_pwd));
|
||||||
let new_pwd = try!(load_password(&args.arg_new_pwd));
|
let new_pwd = try!(load_password(&args.arg_new_pwd));
|
||||||
let ok = store.change_password(&address, &old_pwd, &new_pwd).is_ok();
|
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));
|
let address = try!(store.insert_account(kp.secret().clone(), &password));
|
||||||
Ok(format!("{}", address))
|
Ok(format!("{}", address))
|
||||||
} else if args.cmd_remove {
|
} 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 password = try!(load_password(&args.arg_password));
|
||||||
let ok = store.remove_account(&address, &password).is_ok();
|
let ok = store.remove_account(&address, &password).is_ok();
|
||||||
Ok(format!("{}", ok))
|
Ok(format!("{}", ok))
|
||||||
} else if args.cmd_sign {
|
} else if args.cmd_sign {
|
||||||
let address = try!(Address::from_str(&args.arg_address));
|
let address = try!(args.arg_address.parse().map_err(|_| Error::InvalidAccount));
|
||||||
let message = try!(Message::from_str(&args.arg_message));
|
let message = try!(args.arg_message.parse().map_err(|_| Error::InvalidMessage));
|
||||||
let password = try!(load_password(&args.arg_password));
|
let password = try!(load_password(&args.arg_password));
|
||||||
let signature = try!(store.sign(&address, &password, &message));
|
let signature = try!(store.sign(&address, &password, &message));
|
||||||
Ok(format!("{}", signature))
|
Ok(format!("{}", signature))
|
||||||
|
@ -24,6 +24,7 @@ pub enum Error {
|
|||||||
InvalidPassword,
|
InvalidPassword,
|
||||||
InvalidSecret,
|
InvalidSecret,
|
||||||
InvalidAccount,
|
InvalidAccount,
|
||||||
|
InvalidMessage,
|
||||||
InvalidKeyFile(String),
|
InvalidKeyFile(String),
|
||||||
CreationFailed,
|
CreationFailed,
|
||||||
EthKey(EthKeyError),
|
EthKey(EthKeyError),
|
||||||
@ -37,6 +38,7 @@ impl fmt::Display for Error {
|
|||||||
Error::InvalidPassword => "Invalid password".into(),
|
Error::InvalidPassword => "Invalid password".into(),
|
||||||
Error::InvalidSecret => "Invalid secret".into(),
|
Error::InvalidSecret => "Invalid secret".into(),
|
||||||
Error::InvalidAccount => "Invalid account".into(),
|
Error::InvalidAccount => "Invalid account".into(),
|
||||||
|
Error::InvalidMessage => "Invalid message".into(),
|
||||||
Error::InvalidKeyFile(ref reason) => format!("Invalid key file: {}", reason),
|
Error::InvalidKeyFile(ref reason) => format!("Invalid key file: {}", reason),
|
||||||
Error::CreationFailed => "Account creation failed".into(),
|
Error::CreationFailed => "Account creation failed".into(),
|
||||||
Error::EthKey(ref err) => err.to_string(),
|
Error::EthKey(ref err) => err.to_string(),
|
||||||
|
@ -20,7 +20,7 @@ use std::str::FromStr;
|
|||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer, Error};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer, Error};
|
||||||
use serde::de::Visitor;
|
use serde::de::Visitor;
|
||||||
use rustc_serialize::hex::ToHex;
|
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 {
|
macro_rules! impl_hash {
|
||||||
|
@ -30,7 +30,7 @@ use ethcore::account_provider::AccountProvider;
|
|||||||
use devtools::RandomTempPath;
|
use devtools::RandomTempPath;
|
||||||
use util::Hashable;
|
use util::Hashable;
|
||||||
use io::IoChannel;
|
use io::IoChannel;
|
||||||
use util::{U256, H256, Uint};
|
use util::{U256, H256, Uint, Address};
|
||||||
use jsonrpc_core::IoHandler;
|
use jsonrpc_core::IoHandler;
|
||||||
use ethjson::blockchain::BlockChain;
|
use ethjson::blockchain::BlockChain;
|
||||||
|
|
||||||
@ -416,7 +416,7 @@ fn verify_transaction_counts(name: String, chain: BlockChain) {
|
|||||||
#[test]
|
#[test]
|
||||||
fn starting_nonce_test() {
|
fn starting_nonce_test() {
|
||||||
let tester = EthTester::from_spec(Spec::load(POSITIVE_NONCE_SPEC));
|
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#"
|
let sample = tester.handler.handle_request(&(r#"
|
||||||
{
|
{
|
||||||
|
@ -19,9 +19,7 @@ use std::collections::HashMap;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::{Instant, Duration};
|
use std::time::{Instant, Duration};
|
||||||
use jsonrpc_core::IoHandler;
|
use jsonrpc_core::IoHandler;
|
||||||
use util::hash::{Address, H256, FixedHash};
|
use util::{Uint, U256, Address, H256, FixedHash, Mutex};
|
||||||
use util::{Uint, U256};
|
|
||||||
use util::Mutex;
|
|
||||||
use ethcore::account_provider::AccountProvider;
|
use ethcore::account_provider::AccountProvider;
|
||||||
use ethcore::client::{TestBlockChainClient, EachBlockWith, Executed, TransactionID};
|
use ethcore::client::{TestBlockChainClient, EachBlockWith, Executed, TransactionID};
|
||||||
use ethcore::log_entry::{LocalizedLogEntry, LogEntry};
|
use ethcore::log_entry::{LocalizedLogEntry, LogEntry};
|
||||||
@ -187,7 +185,7 @@ fn rpc_eth_sign() {
|
|||||||
],
|
],
|
||||||
"id": 1
|
"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));
|
assert_eq!(tester.io.handle_request(&req), Some(res));
|
||||||
}
|
}
|
||||||
|
@ -185,7 +185,7 @@ fn should_sign_if_account_is_unlocked() {
|
|||||||
],
|
],
|
||||||
"id": 1
|
"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.io.handle_request(&request), Some(response.to_owned()));
|
||||||
assert_eq!(tester.queue.requests().len(), 0);
|
assert_eq!(tester.queue.requests().len(), 0);
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ use std::cmp::Ordering;
|
|||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use serde;
|
use serde;
|
||||||
use rustc_serialize::hex::{ToHex, FromHex};
|
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 {
|
macro_rules! impl_hash {
|
||||||
($name: ident, $other: ident, $size: expr) => {
|
($name: ident, $other: ident, $size: expr) => {
|
||||||
@ -143,7 +143,7 @@ macro_rules! impl_hash {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl_hash!(H64, Eth64, 8);
|
impl_hash!(H64, Eth64, 8);
|
||||||
impl_hash!(H160, Address, 20);
|
impl_hash!(H160, Eth160, 20);
|
||||||
impl_hash!(H256, EthH256, 32);
|
impl_hash!(H256, EthH256, 32);
|
||||||
impl_hash!(H520, EthH520, 65);
|
impl_hash!(H520, EthH520, 65);
|
||||||
impl_hash!(H2048, Eth2048, 256);
|
impl_hash!(H2048, Eth2048, 256);
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
//! General hash types, a fixed-size raw-data type used as the output of hash functions.
|
//! General hash types, a fixed-size raw-data type used as the output of hash functions.
|
||||||
|
|
||||||
use std::{ops, fmt, cmp};
|
use std::{ops, fmt, cmp};
|
||||||
use std::cmp::*;
|
use std::cmp::{min, Ordering};
|
||||||
use std::ops::*;
|
use std::ops::{Deref, DerefMut, BitXor, BitAnd, BitOr, IndexMut, Index};
|
||||||
use std::hash::{Hash, Hasher, BuildHasherDefault};
|
use std::hash::{Hash, Hasher, BuildHasherDefault};
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::str::FromStr;
|
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 {
|
impl Deref for $from {
|
||||||
type Target = [u8];
|
type Target = [u8];
|
||||||
|
|
||||||
@ -409,9 +415,9 @@ impl<'a> From<&'a H256> for U256 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<H256> for Address {
|
impl From<H256> for H160 {
|
||||||
fn from(value: H256) -> Address {
|
fn from(value: H256) -> H160 {
|
||||||
let mut ret = Address::new();
|
let mut ret = H160::new();
|
||||||
ret.0.copy_from_slice(&value[12..32]);
|
ret.0.copy_from_slice(&value[12..32]);
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
@ -425,16 +431,16 @@ impl From<H256> for H64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Address> for H256 {
|
impl From<H160> for H256 {
|
||||||
fn from(value: Address) -> H256 {
|
fn from(value: H160) -> H256 {
|
||||||
let mut ret = H256::new();
|
let mut ret = H256::new();
|
||||||
ret.0[12..32].copy_from_slice(&value);
|
ret.0[12..32].copy_from_slice(&value);
|
||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a Address> for H256 {
|
impl<'a> From<&'a H160> for H256 {
|
||||||
fn from(value: &'a Address) -> H256 {
|
fn from(value: &'a H160) -> H256 {
|
||||||
let mut ret = H256::new();
|
let mut ret = H256::new();
|
||||||
ret.0[12..32].copy_from_slice(value);
|
ret.0[12..32].copy_from_slice(value);
|
||||||
ret
|
ret
|
||||||
@ -444,7 +450,7 @@ impl<'a> From<&'a Address> for H256 {
|
|||||||
impl_hash!(H32, 4);
|
impl_hash!(H32, 4);
|
||||||
impl_hash!(H64, 8);
|
impl_hash!(H64, 8);
|
||||||
impl_hash!(H128, 16);
|
impl_hash!(H128, 16);
|
||||||
impl_hash!(Address, 20);
|
impl_hash!(H160, 20);
|
||||||
impl_hash!(H256, 32);
|
impl_hash!(H256, 32);
|
||||||
impl_hash!(H264, 33);
|
impl_hash!(H264, 33);
|
||||||
impl_hash!(H512, 64);
|
impl_hash!(H512, 64);
|
||||||
@ -452,7 +458,7 @@ impl_hash!(H520, 65);
|
|||||||
impl_hash!(H1024, 128);
|
impl_hash!(H1024, 128);
|
||||||
impl_hash!(H2048, 256);
|
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
|
// Specialized HashMap and HashSet
|
||||||
|
|
||||||
/// Hasher that just takes 8 bytes of the provided value.
|
/// Hasher that just takes 8 bytes of the provided value.
|
||||||
@ -535,9 +541,9 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn from_and_to_address() {
|
fn from_and_to_address() {
|
||||||
let address = Address::from_str("ef2d6d194084c2de36e0dabfce45d046b37d1106").unwrap();
|
let address: H160 = "ef2d6d194084c2de36e0dabfce45d046b37d1106".into();
|
||||||
let h = H256::from(address.clone());
|
let h = H256::from(address.clone());
|
||||||
let a = Address::from(h);
|
let a = H160::from(h);
|
||||||
assert_eq!(address, a);
|
assert_eq!(address, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,14 +36,11 @@
|
|||||||
//! The functions here are designed to be fast.
|
//! The functions here are designed to be fast.
|
||||||
//!
|
//!
|
||||||
|
|
||||||
use std::mem;
|
use std::{mem, fmt};
|
||||||
use std::fmt;
|
|
||||||
use std::str::{FromStr};
|
use std::str::{FromStr};
|
||||||
use std::convert::From;
|
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use std::ops::*;
|
use std::ops::{Shr, Shl, BitAnd, BitOr, BitXor, Not, Div, Rem, Mul, Add, Sub};
|
||||||
use std::cmp::*;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
use rustc_serialize::hex::{FromHex, FromHexError};
|
use rustc_serialize::hex::{FromHex, FromHexError};
|
||||||
|
|
||||||
/// Conversion from decimal string error
|
/// 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]));
|
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);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::DerefMut;
|
use std::ops::DerefMut;
|
||||||
use {H64, Address, H256, H512, H520, H2048, FixedHash};
|
use {H64, H160, H256, H512, H520, H2048, FixedHash};
|
||||||
|
|
||||||
/// Returns log2.
|
/// Returns log2.
|
||||||
pub fn log2(x: usize) -> u32 {
|
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!(H64, 8);
|
||||||
impl_bloomable_for_hash!(Address, 20);
|
impl_bloomable_for_hash!(H160, 20);
|
||||||
impl_bloomable_for_hash!(H256, 32);
|
impl_bloomable_for_hash!(H256, 32);
|
||||||
impl_bloomable_for_hash!(H512, 64);
|
impl_bloomable_for_hash!(H512, 64);
|
||||||
impl_bloomable_for_hash!(H520, 65);
|
impl_bloomable_for_hash!(H520, 65);
|
||||||
@ -118,14 +118,14 @@ impl_bloomable_for_hash!(H2048, 256);
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use {Address, H256, H2048};
|
use {H160, H256, H2048};
|
||||||
use sha3::Hashable;
|
use sha3::Hashable;
|
||||||
use super::Bloomable;
|
use super::Bloomable;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn shift_bloomed() {
|
fn shift_bloomed() {
|
||||||
let bloom: H2048 = "00000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020000000000000000000000000000000000000000000008000000001000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".into();
|
let bloom: H2048 = "00000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020000000000000000000000000000000000000000000008000000001000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000".into();
|
||||||
let address: Address = "ef2d6d194084c2de36e0dabfce45d046b37d1106".into();
|
let address: H160 = "ef2d6d194084c2de36e0dabfce45d046b37d1106".into();
|
||||||
let topic: H256 = "02c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc".into();
|
let topic: H256 = "02c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc".into();
|
||||||
|
|
||||||
let mut my_bloom = H2048::default();
|
let mut my_bloom = H2048::default();
|
||||||
|
@ -232,7 +232,7 @@ fn fax_raw_dyn() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn populate_big_types() {
|
fn populate_big_types() {
|
||||||
use hash::*;
|
use hash::*;
|
||||||
let a: Address = "ffffffffffffffffffffffffffffffffffffffff".into();
|
let a: H160 = "ffffffffffffffffffffffffffffffffffffffff".into();
|
||||||
let mut h: H256 = 0x69.into();
|
let mut h: H256 = 0x69.into();
|
||||||
h.populate_raw_from(&a);
|
h.populate_raw_from(&a);
|
||||||
assert_eq!(h, "ffffffffffffffffffffffffffffffffffffffff000000000000000000000000".into());
|
assert_eq!(h, "ffffffffffffffffffffffffffffffffffffffff000000000000000000000000".into());
|
||||||
|
@ -23,6 +23,7 @@ use secp256k1::{key, Secp256k1};
|
|||||||
use rand::os::OsRng;
|
use rand::os::OsRng;
|
||||||
use sha3::Hashable;
|
use sha3::Hashable;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
use Address;
|
||||||
|
|
||||||
/// Secret key for secp256k1 EC operations. 256 bit generic "hash" data.
|
/// Secret key for secp256k1 EC operations. 256 bit generic "hash" data.
|
||||||
pub type Secret = H256;
|
pub type Secret = H256;
|
||||||
|
@ -156,59 +156,5 @@ pub use log::*;
|
|||||||
pub use kvdb::*;
|
pub use kvdb::*;
|
||||||
pub use timer::*;
|
pub use timer::*;
|
||||||
|
|
||||||
#[cfg(test)]
|
pub type Address = H160;
|
||||||
mod tests {
|
|
||||||
use std::str::FromStr;
|
|
||||||
use {U256, H256, Uint};
|
|
||||||
|
|
||||||
#[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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -22,7 +22,7 @@ use std::fmt;
|
|||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::error::Error as StdError;
|
use std::error::Error as StdError;
|
||||||
use bigint::uint::{Uint, U128, U256};
|
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::*;
|
use elastic_array::*;
|
||||||
|
|
||||||
/// Vector like object
|
/// Vector like object
|
||||||
@ -159,7 +159,7 @@ macro_rules! impl_hash_to_bytes {
|
|||||||
|
|
||||||
impl_hash_to_bytes!(H64);
|
impl_hash_to_bytes!(H64);
|
||||||
impl_hash_to_bytes!(H128);
|
impl_hash_to_bytes!(H128);
|
||||||
impl_hash_to_bytes!(Address);
|
impl_hash_to_bytes!(H160);
|
||||||
impl_hash_to_bytes!(H256);
|
impl_hash_to_bytes!(H256);
|
||||||
impl_hash_to_bytes!(H512);
|
impl_hash_to_bytes!(H512);
|
||||||
impl_hash_to_bytes!(H520);
|
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!(H64, 8);
|
||||||
impl_hash_from_bytes!(H128, 16);
|
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!(H256, 32);
|
||||||
impl_hash_from_bytes!(H512, 64);
|
impl_hash_from_bytes!(H512, 64);
|
||||||
impl_hash_from_bytes!(H520, 65);
|
impl_hash_from_bytes!(H520, 65);
|
||||||
|
@ -168,7 +168,7 @@ fn encode_address() {
|
|||||||
use hash::*;
|
use hash::*;
|
||||||
|
|
||||||
let tests = vec![
|
let tests = vec![
|
||||||
ETestPair(Address::from_str("ef2d6d194084c2de36e0dabfce45d046b37d1106").unwrap(),
|
ETestPair(H160::from("ef2d6d194084c2de36e0dabfce45d046b37d1106"),
|
||||||
vec![0x94, 0xef, 0x2d, 0x6d, 0x19, 0x40, 0x84, 0xc2, 0xde,
|
vec![0x94, 0xef, 0x2d, 0x6d, 0x19, 0x40, 0x84, 0xc2, 0xde,
|
||||||
0x36, 0xe0, 0xda, 0xbf, 0xce, 0x45, 0xd0, 0x46,
|
0x36, 0xe0, 0xda, 0xbf, 0xce, 0x45, 0xd0, 0x46,
|
||||||
0xb3, 0x7d, 0x11, 0x06])
|
0xb3, 0x7d, 0x11, 0x06])
|
||||||
@ -304,7 +304,7 @@ fn decode_untrusted_address() {
|
|||||||
use hash::*;
|
use hash::*;
|
||||||
|
|
||||||
let tests = vec![
|
let tests = vec![
|
||||||
DTestPair(Address::from_str("ef2d6d194084c2de36e0dabfce45d046b37d1106").unwrap(),
|
DTestPair(H160::from("ef2d6d194084c2de36e0dabfce45d046b37d1106"),
|
||||||
vec![0x94, 0xef, 0x2d, 0x6d, 0x19, 0x40, 0x84, 0xc2, 0xde,
|
vec![0x94, 0xef, 0x2d, 0x6d, 0x19, 0x40, 0x84, 0xc2, 0xde,
|
||||||
0x36, 0xe0, 0xda, 0xbf, 0xce, 0x45, 0xd0, 0x46,
|
0x36, 0xe0, 0xda, 0xbf, 0xce, 0x45, 0xd0, 0x46,
|
||||||
0xb3, 0x7d, 0x11, 0x06])
|
0xb3, 0x7d, 0x11, 0x06])
|
||||||
|
Loading…
Reference in New Issue
Block a user