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:
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
//! Interface for Evm externalities.
|
||||
|
||||
use util::common::*;
|
||||
use util::*;
|
||||
use evm::{self, Schedule};
|
||||
use env_info::*;
|
||||
use types::executed::CallType;
|
||||
|
||||
@@ -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};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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::*;
|
||||
|
||||
@@ -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![]
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user