Merge branch 'master' into client-refact

This commit is contained in:
Nikolay Volf 2016-06-01 12:45:04 +02:00
commit 0c782bf34b
29 changed files with 814 additions and 480 deletions

View File

@ -8,17 +8,19 @@ authors = ["Ethcore <admin@ethcore.io>"]
build = "build.rs" build = "build.rs"
[build-dependencies] [build-dependencies]
syntex = "*" syntex = "0.32"
ethcore-ipc-codegen = { path = "../ipc/codegen" } ethcore-ipc-codegen = { path = "../ipc/codegen" }
[dependencies] [dependencies]
ethcore-util = { path = "../util" }
clippy = { version = "0.0.67", optional = true} clippy = { version = "0.0.67", optional = true}
ethcore-devtools = { path = "../devtools" } ethcore-devtools = { path = "../devtools" }
ethcore-ipc = { path = "../ipc/rpc" } ethcore-ipc = { path = "../ipc/rpc" }
rocksdb = { git = "https://github.com/ethcore/rust-rocksdb" } rocksdb = { git = "https://github.com/ethcore/rust-rocksdb" }
semver = "0.2" semver = "0.2"
ethcore-ipc-nano = { path = "../ipc/nano" } ethcore-ipc-nano = { path = "../ipc/nano" }
nanomsg = { git = "https://github.com/ethcore/nanomsg.rs.git" }
crossbeam = "0.2"
ethcore-util = { path = "../util" }
[features] [features]
dev = ["clippy"] dev = ["clippy"]

View File

@ -18,15 +18,13 @@
use traits::*; use traits::*;
use rocksdb::{DB, Writable, WriteBatch, IteratorMode, DBIterator, use rocksdb::{DB, Writable, WriteBatch, IteratorMode, DBIterator,
IndexType, Options, DBCompactionStyle, BlockBasedOptions, Direction}; IndexType, Options, DBCompactionStyle, BlockBasedOptions, Direction};
use std::collections::BTreeMap; use std::sync::{RwLock, Arc};
use std::sync::{RwLock};
use std::convert::From; use std::convert::From;
use ipc::IpcConfig; use ipc::IpcConfig;
use std::ops::*;
use std::mem; use std::mem;
use ipc::binary::BinaryConvertError; use ipc::binary::BinaryConvertError;
use std::collections::VecDeque; use std::collections::{VecDeque, HashMap, BTreeMap};
impl From<String> for Error { impl From<String> for Error {
fn from(s: String) -> Error { fn from(s: String) -> Error {
@ -34,20 +32,136 @@ impl From<String> for Error {
} }
} }
enum WriteCacheEntry {
Remove,
Write(Vec<u8>),
}
pub struct WriteCache {
entries: HashMap<Vec<u8>, WriteCacheEntry>,
preferred_len: usize,
}
const FLUSH_BATCH_SIZE: usize = 4096;
impl WriteCache {
fn new(cache_len: usize) -> WriteCache {
WriteCache {
entries: HashMap::new(),
preferred_len: cache_len,
}
}
fn write(&mut self, key: Vec<u8>, val: Vec<u8>) {
self.entries.insert(key, WriteCacheEntry::Write(val));
}
fn remove(&mut self, key: Vec<u8>) {
self.entries.insert(key, WriteCacheEntry::Remove);
}
fn get(&self, key: &Vec<u8>) -> Option<Vec<u8>> {
self.entries.get(key).and_then(
|vec_ref| match vec_ref {
&WriteCacheEntry::Write(ref val) => Some(val.clone()),
&WriteCacheEntry::Remove => None
})
}
/// WriteCache should be locked for this
fn flush(&mut self, db: &DB, amount: usize) -> Result<(), Error> {
let batch = WriteBatch::new();
let mut removed_so_far = 0;
while removed_so_far < amount {
if self.entries.len() == 0 { break; }
let removed_key = {
let (key, cache_entry) = self.entries.iter().nth(0)
.expect("if entries.len == 0, we should have break in the loop, still we got here somehow");
match *cache_entry {
WriteCacheEntry::Write(ref val) => {
try!(batch.put(&key, val));
},
WriteCacheEntry::Remove => {
try!(batch.delete(&key));
},
}
key.clone()
};
self.entries.remove(&removed_key);
removed_so_far = removed_so_far + 1;
}
if removed_so_far > 0 {
try!(db.write(batch));
}
Ok(())
}
/// flushes until cache is empty
fn flush_all(&mut self, db: &DB) -> Result<(), Error> {
while !self.is_empty() { try!(self.flush(db, FLUSH_BATCH_SIZE)); }
Ok(())
}
fn is_empty(&self) -> bool {
self.entries.is_empty()
}
fn try_shrink(&mut self, db: &DB) -> Result<(), Error> {
if self.entries.len() > self.preferred_len {
try!(self.flush(db, FLUSH_BATCH_SIZE));
}
Ok(())
}
}
pub struct Database { pub struct Database {
db: RwLock<Option<DB>>, db: RwLock<Option<DB>>,
transactions: RwLock<BTreeMap<TransactionHandle, WriteBatch>>, /// Iterators - dont't use between threads!
iterators: RwLock<BTreeMap<IteratorHandle, DBIterator>>, iterators: RwLock<BTreeMap<IteratorHandle, DBIterator>>,
write_cache: RwLock<WriteCache>,
} }
unsafe impl Send for Database {}
unsafe impl Sync for Database {}
impl Database { impl Database {
pub fn new() -> Database { pub fn new() -> Database {
Database { Database {
db: RwLock::new(None), db: RwLock::new(None),
transactions: RwLock::new(BTreeMap::new()),
iterators: RwLock::new(BTreeMap::new()), iterators: RwLock::new(BTreeMap::new()),
write_cache: RwLock::new(WriteCache::new(DEFAULT_CACHE_LEN)),
} }
} }
pub fn flush(&self) -> Result<(), Error> {
let mut cache_lock = self.write_cache.write().unwrap();
let db_lock = self.db.read().unwrap();
if db_lock.is_none() { return Ok(()); }
let db = db_lock.as_ref().unwrap();
try!(cache_lock.try_shrink(&db));
Ok(())
}
pub fn flush_all(&self) -> Result<(), Error> {
let mut cache_lock = self.write_cache.write().unwrap();
let db_lock = self.db.read().unwrap();
if db_lock.is_none() { return Ok(()); }
let db = db_lock.as_ref().expect("we should have exited with Ok(()) on the previous step");
try!(cache_lock.flush_all(&db));
Ok(())
}
}
impl Drop for Database {
fn drop(&mut self) {
self.flush().unwrap();
}
} }
#[derive(Ipc)] #[derive(Ipc)]
@ -72,51 +186,64 @@ impl DatabaseService for Database {
Ok(()) Ok(())
} }
/// Opens database in the specified path with the default config
fn open_default(&self, path: String) -> Result<(), Error> {
self.open(DatabaseConfig::default(), path)
}
fn close(&self) -> Result<(), Error> { fn close(&self) -> Result<(), Error> {
try!(self.flush_all());
let mut db = self.db.write().unwrap(); let mut db = self.db.write().unwrap();
if db.is_none() { return Err(Error::IsClosed); } if db.is_none() { return Err(Error::IsClosed); }
// TODO: wait for transactions to expire/close here?
if self.transactions.read().unwrap().len() > 0 { return Err(Error::UncommitedTransactions); }
*db = None; *db = None;
Ok(()) Ok(())
} }
fn put(&self, key: &[u8], value: &[u8]) -> Result<(), Error> { fn put(&self, key: &[u8], value: &[u8]) -> Result<(), Error> {
let db_lock = self.db.read().unwrap(); let mut cache_lock = self.write_cache.write().unwrap();
let db = try!(db_lock.as_ref().ok_or(Error::IsClosed)); cache_lock.write(key.to_vec(), value.to_vec());
try!(db.put(key, value));
Ok(()) Ok(())
} }
fn delete(&self, key: &[u8]) -> Result<(), Error> { fn delete(&self, key: &[u8]) -> Result<(), Error> {
let db_lock = self.db.read().unwrap(); let mut cache_lock = self.write_cache.write().unwrap();
let db = try!(db_lock.as_ref().ok_or(Error::IsClosed)); cache_lock.remove(key.to_vec());
try!(db.delete(key));
Ok(()) Ok(())
} }
fn write(&self, handle: TransactionHandle) -> Result<(), Error> { fn write(&self, transaction: DBTransaction) -> Result<(), Error> {
let db_lock = self.db.read().unwrap(); let mut cache_lock = self.write_cache.write().unwrap();
let db = try!(db_lock.as_ref().ok_or(Error::IsClosed));
let mut transactions = self.transactions.write().unwrap(); let mut writes = transaction.writes.borrow_mut();
let batch = try!( for kv in writes.drain(..) {
transactions.remove(&handle).ok_or(Error::TransactionUnknown) cache_lock.write(kv.key, kv.value);
); }
try!(db.write(batch));
let mut removes = transaction.removes.borrow_mut();
for k in removes.drain(..) {
cache_lock.remove(k);
}
Ok(()) Ok(())
} }
fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error> { fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error> {
{
let key_vec = key.to_vec();
let cache_hit = self.write_cache.read().unwrap().get(&key_vec);
if cache_hit.is_some() {
return Ok(Some(cache_hit.expect("cache_hit.is_some() = true, still there is none somehow here")))
}
}
let db_lock = self.db.read().unwrap(); let db_lock = self.db.read().unwrap();
let db = try!(db_lock.as_ref().ok_or(Error::IsClosed)); let db = try!(db_lock.as_ref().ok_or(Error::IsClosed));
match try!(db.get(key)) { match try!(db.get(key)) {
Some(db_vec) => Ok(Some(db_vec.to_vec())), Some(db_vec) => {
Ok(Some(db_vec.to_vec()))
},
None => Ok(None), None => Ok(None),
} }
} }
@ -166,37 +293,35 @@ impl DatabaseService for Database {
}) })
} }
fn transaction_put(&self, transaction: TransactionHandle, key: &[u8], value: &[u8]) -> Result<(), Error> fn dispose_iter(&self, handle: IteratorHandle) -> Result<(), Error> {
{ let mut iterators = self.iterators.write().unwrap();
let mut transactions = self.transactions.write().unwrap(); iterators.remove(&handle);
let batch = try!(
transactions.get_mut(&transaction).ok_or(Error::TransactionUnknown)
);
try!(batch.put(&key, &value));
Ok(()) Ok(())
} }
fn transaction_delete(&self, transaction: TransactionHandle, key: &[u8]) -> Result<(), Error> {
let mut transactions = self.transactions.write().unwrap();
let batch = try!(
transactions.get_mut(&transaction).ok_or(Error::TransactionUnknown)
);
try!(batch.delete(&key));
Ok(())
}
fn new_transaction(&self) -> TransactionHandle {
let mut transactions = self.transactions.write().unwrap();
let next_transaction = transactions.keys().last().unwrap_or(&0) + 1;
transactions.insert(next_transaction, WriteBatch::new());
next_transaction
}
} }
// TODO : put proper at compile-time // TODO : put proper at compile-time
impl IpcConfig for Database {} impl IpcConfig for Database {}
/// Database iterator
pub struct DatabaseIterator {
client: Arc<DatabaseClient<::nanomsg::Socket>>,
handle: IteratorHandle,
}
impl Iterator for DatabaseIterator {
type Item = (Vec<u8>, Vec<u8>);
fn next(&mut self) -> Option<Self::Item> {
self.client.iter_next(self.handle).and_then(|kv| Some((kv.key, kv.value)))
}
}
impl Drop for DatabaseIterator {
fn drop(&mut self) {
self.client.dispose_iter(self.handle).unwrap();
}
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {
@ -215,7 +340,7 @@ mod test {
fn can_be_open_empty() { fn can_be_open_empty() {
let db = Database::new(); let db = Database::new();
let path = RandomTempPath::create_dir(); let path = RandomTempPath::create_dir();
db.open(DatabaseConfig { prefix_size: Some(8) }, path.as_str().to_owned()).unwrap(); db.open_default(path.as_str().to_owned()).unwrap();
assert!(db.is_empty().is_ok()); assert!(db.is_empty().is_ok());
} }
@ -224,9 +349,10 @@ mod test {
fn can_store_key() { fn can_store_key() {
let db = Database::new(); let db = Database::new();
let path = RandomTempPath::create_dir(); let path = RandomTempPath::create_dir();
db.open(DatabaseConfig { prefix_size: None }, path.as_str().to_owned()).unwrap(); db.open_default(path.as_str().to_owned()).unwrap();
db.put("xxx".as_bytes(), "1".as_bytes()).unwrap(); db.put("xxx".as_bytes(), "1".as_bytes()).unwrap();
db.flush_all().unwrap();
assert!(!db.is_empty().unwrap()); assert!(!db.is_empty().unwrap());
} }
@ -234,15 +360,37 @@ mod test {
fn can_retrieve() { fn can_retrieve() {
let db = Database::new(); let db = Database::new();
let path = RandomTempPath::create_dir(); let path = RandomTempPath::create_dir();
db.open(DatabaseConfig { prefix_size: None }, path.as_str().to_owned()).unwrap(); db.open_default(path.as_str().to_owned()).unwrap();
db.put("xxx".as_bytes(), "1".as_bytes()).unwrap(); db.put("xxx".as_bytes(), "1".as_bytes()).unwrap();
db.close().unwrap(); db.close().unwrap();
db.open(DatabaseConfig { prefix_size: None }, path.as_str().to_owned()).unwrap(); db.open_default(path.as_str().to_owned()).unwrap();
assert_eq!(db.get("xxx".as_bytes()).unwrap().unwrap(), "1".as_bytes().to_vec()); assert_eq!(db.get("xxx".as_bytes()).unwrap().unwrap(), "1".as_bytes().to_vec());
} }
} }
#[cfg(test)]
mod write_cache_tests {
use super::Database;
use traits::*;
use devtools::*;
#[test]
fn cache_write_flush() {
let db = Database::new();
let path = RandomTempPath::create_dir();
db.open_default(path.as_str().to_owned()).unwrap();
db.put("100500".as_bytes(), "1".as_bytes()).unwrap();
db.delete("100500".as_bytes()).unwrap();
db.flush_all().unwrap();
let val = db.get("100500".as_bytes()).unwrap();
assert!(val.is_none());
}
}
#[cfg(test)] #[cfg(test)]
mod client_tests { mod client_tests {
use super::{DatabaseClient, Database}; use super::{DatabaseClient, Database};
@ -251,6 +399,8 @@ mod client_tests {
use nanoipc; use nanoipc;
use std::sync::Arc; use std::sync::Arc;
use std::sync::atomic::{Ordering, AtomicBool}; use std::sync::atomic::{Ordering, AtomicBool};
use crossbeam;
use run_worker;
fn init_worker(addr: &str) -> nanoipc::Worker<Database> { fn init_worker(addr: &str) -> nanoipc::Worker<Database> {
let mut worker = nanoipc::Worker::<Database>::new(&Arc::new(Database::new())); let mut worker = nanoipc::Worker::<Database>::new(&Arc::new(Database::new()));
@ -268,7 +418,7 @@ mod client_tests {
::std::thread::spawn(move || { ::std::thread::spawn(move || {
let mut worker = init_worker(url); let mut worker = init_worker(url);
while !c_worker_should_exit.load(Ordering::Relaxed) { while !c_worker_should_exit.load(Ordering::Relaxed) {
worker.poll(); worker.poll();
c_worker_is_ready.store(true, Ordering::Relaxed); c_worker_is_ready.store(true, Ordering::Relaxed);
} }
@ -295,7 +445,7 @@ mod client_tests {
::std::thread::spawn(move || { ::std::thread::spawn(move || {
let mut worker = init_worker(url); let mut worker = init_worker(url);
while !c_worker_should_exit.load(Ordering::Relaxed) { while !c_worker_should_exit.load(Ordering::Relaxed) {
worker.poll(); worker.poll();
c_worker_is_ready.store(true, Ordering::Relaxed); c_worker_is_ready.store(true, Ordering::Relaxed);
} }
@ -304,7 +454,7 @@ mod client_tests {
while !worker_is_ready.load(Ordering::Relaxed) { } while !worker_is_ready.load(Ordering::Relaxed) { }
let client = nanoipc::init_duplex_client::<DatabaseClient<_>>(url).unwrap(); let client = nanoipc::init_duplex_client::<DatabaseClient<_>>(url).unwrap();
client.open(DatabaseConfig { prefix_size: Some(8) }, path.as_str().to_owned()).unwrap(); client.open_default(path.as_str().to_owned()).unwrap();
assert!(client.is_empty().unwrap()); assert!(client.is_empty().unwrap());
worker_should_exit.store(true, Ordering::Relaxed); worker_should_exit.store(true, Ordering::Relaxed);
} }
@ -314,27 +464,16 @@ mod client_tests {
let url = "ipc:///tmp/parity-db-ipc-test-30.ipc"; let url = "ipc:///tmp/parity-db-ipc-test-30.ipc";
let path = RandomTempPath::create_dir(); let path = RandomTempPath::create_dir();
let worker_should_exit = Arc::new(AtomicBool::new(false)); crossbeam::scope(move |scope| {
let worker_is_ready = Arc::new(AtomicBool::new(false)); let stop = Arc::new(AtomicBool::new(false));
let c_worker_should_exit = worker_should_exit.clone(); run_worker(scope, stop.clone(), url);
let c_worker_is_ready = worker_is_ready.clone(); let client = nanoipc::init_client::<DatabaseClient<_>>(url).unwrap();
client.open_default(path.as_str().to_owned()).unwrap();
client.put("xxx".as_bytes(), "1".as_bytes()).unwrap();
client.close().unwrap();
::std::thread::spawn(move || { stop.store(true, Ordering::Relaxed);
let mut worker = init_worker(url);
while !c_worker_should_exit.load(Ordering::Relaxed) {
worker.poll();
c_worker_is_ready.store(true, Ordering::Relaxed);
}
}); });
while !worker_is_ready.load(Ordering::Relaxed) { }
let client = nanoipc::init_duplex_client::<DatabaseClient<_>>(url).unwrap();
client.open(DatabaseConfig { prefix_size: Some(8) }, path.as_str().to_owned()).unwrap();
client.put("xxx".as_bytes(), "1".as_bytes()).unwrap();
client.close().unwrap();
worker_should_exit.store(true, Ordering::Relaxed);
} }
#[test] #[test]
@ -342,29 +481,93 @@ mod client_tests {
let url = "ipc:///tmp/parity-db-ipc-test-40.ipc"; let url = "ipc:///tmp/parity-db-ipc-test-40.ipc";
let path = RandomTempPath::create_dir(); let path = RandomTempPath::create_dir();
let worker_should_exit = Arc::new(AtomicBool::new(false)); crossbeam::scope(move |scope| {
let worker_is_ready = Arc::new(AtomicBool::new(false)); let stop = Arc::new(AtomicBool::new(false));
let c_worker_should_exit = worker_should_exit.clone(); run_worker(scope, stop.clone(), url);
let c_worker_is_ready = worker_is_ready.clone(); let client = nanoipc::init_client::<DatabaseClient<_>>(url).unwrap();
::std::thread::spawn(move || { client.open_default(path.as_str().to_owned()).unwrap();
let mut worker = init_worker(url); client.put("xxx".as_bytes(), "1".as_bytes()).unwrap();
while !c_worker_should_exit.load(Ordering::Relaxed) { client.close().unwrap();
worker.poll();
c_worker_is_ready.store(true, Ordering::Relaxed); client.open_default(path.as_str().to_owned()).unwrap();
assert_eq!(client.get("xxx".as_bytes()).unwrap().unwrap(), "1".as_bytes().to_vec());
stop.store(true, Ordering::Relaxed);
});
}
#[test]
fn can_read_empty() {
let url = "ipc:///tmp/parity-db-ipc-test-45.ipc";
let path = RandomTempPath::create_dir();
crossbeam::scope(move |scope| {
let stop = Arc::new(AtomicBool::new(false));
run_worker(scope, stop.clone(), url);
let client = nanoipc::init_client::<DatabaseClient<_>>(url).unwrap();
client.open_default(path.as_str().to_owned()).unwrap();
assert!(client.get("xxx".as_bytes()).unwrap().is_none());
stop.store(true, Ordering::Relaxed);
});
}
#[test]
fn can_commit_client_transaction() {
let url = "ipc:///tmp/parity-db-ipc-test-60.ipc";
let path = RandomTempPath::create_dir();
crossbeam::scope(move |scope| {
let stop = Arc::new(AtomicBool::new(false));
run_worker(scope, stop.clone(), url);
let client = nanoipc::init_client::<DatabaseClient<_>>(url).unwrap();
client.open_default(path.as_str().to_owned()).unwrap();
let transaction = DBTransaction::new();
transaction.put("xxx".as_bytes(), "1".as_bytes());
client.write(transaction).unwrap();
client.close().unwrap();
client.open_default(path.as_str().to_owned()).unwrap();
assert_eq!(client.get("xxx".as_bytes()).unwrap().unwrap(), "1".as_bytes().to_vec());
stop.store(true, Ordering::Relaxed);
});
}
#[test]
fn key_write_read_ipc() {
let url = "ipc:///tmp/parity-db-ipc-test-70.ipc";
let path = RandomTempPath::create_dir();
crossbeam::scope(|scope| {
let stop = StopGuard::new();
run_worker(&scope, stop.share(), url);
let client = nanoipc::init_client::<DatabaseClient<_>>(url).unwrap();
client.open_default(path.as_str().to_owned()).unwrap();
let mut batch = Vec::new();
for _ in 0..100 {
batch.push((random_str(256).as_bytes().to_vec(), random_str(256).as_bytes().to_vec()));
batch.push((random_str(256).as_bytes().to_vec(), random_str(2048).as_bytes().to_vec()));
batch.push((random_str(2048).as_bytes().to_vec(), random_str(2048).as_bytes().to_vec()));
batch.push((random_str(2048).as_bytes().to_vec(), random_str(256).as_bytes().to_vec()));
}
for &(ref k, ref v) in batch.iter() {
client.put(k, v).unwrap();
}
client.close().unwrap();
client.open_default(path.as_str().to_owned()).unwrap();
for &(ref k, ref v) in batch.iter() {
assert_eq!(v, &client.get(k).unwrap().unwrap());
} }
}); });
while !worker_is_ready.load(Ordering::Relaxed) { }
let client = nanoipc::init_duplex_client::<DatabaseClient<_>>(url).unwrap();
client.open(DatabaseConfig { prefix_size: Some(8) }, path.as_str().to_owned()).unwrap();
client.put("xxx".as_bytes(), "1".as_bytes()).unwrap();
client.close().unwrap();
client.open(DatabaseConfig { prefix_size: Some(8) }, path.as_str().to_owned()).unwrap();
assert_eq!(client.get("xxx".as_bytes()).unwrap().unwrap(), "1".as_bytes().to_vec());
worker_should_exit.store(true, Ordering::Relaxed);
} }
} }

View File

@ -19,7 +19,71 @@ extern crate rocksdb;
extern crate ethcore_devtools as devtools; extern crate ethcore_devtools as devtools;
extern crate semver; extern crate semver;
extern crate ethcore_ipc_nano as nanoipc; extern crate ethcore_ipc_nano as nanoipc;
extern crate nanomsg;
extern crate crossbeam;
extern crate ethcore_util as util; extern crate ethcore_util as util;
pub mod database; pub mod database;
pub mod traits; pub mod traits;
pub use traits::{DatabaseService, DBTransaction, Error};
pub use database::{Database, DatabaseClient, DatabaseIterator};
use std::sync::Arc;
use std::sync::atomic::*;
use std::path::PathBuf;
pub type DatabaseNanoClient = DatabaseClient<::nanomsg::Socket>;
pub type DatabaseConnection = nanoipc::GuardedSocket<DatabaseNanoClient>;
#[derive(Debug)]
pub enum ServiceError {
Io(std::io::Error),
Socket(nanoipc::SocketError),
}
impl std::convert::From<std::io::Error> for ServiceError {
fn from(io_error: std::io::Error) -> ServiceError { ServiceError::Io(io_error) }
}
impl std::convert::From<nanoipc::SocketError> for ServiceError {
fn from(socket_error: nanoipc::SocketError) -> ServiceError { ServiceError::Socket(socket_error) }
}
pub fn blocks_service_url(db_path: &str) -> Result<String, std::io::Error> {
let mut path = PathBuf::from(db_path);
try!(::std::fs::create_dir_all(db_path));
path.push("blocks.ipc");
Ok(format!("ipc://{}", path.to_str().unwrap()))
}
pub fn extras_service_url(db_path: &str) -> Result<String, ::std::io::Error> {
let mut path = PathBuf::from(db_path);
try!(::std::fs::create_dir_all(db_path));
path.push("extras.ipc");
Ok(format!("ipc://{}", path.to_str().unwrap()))
}
pub fn blocks_client(db_path: &str) -> Result<DatabaseConnection, ServiceError> {
let url = try!(blocks_service_url(db_path));
let client = try!(nanoipc::init_client::<DatabaseClient<_>>(&url));
Ok(client)
}
pub fn extras_client(db_path: &str) -> Result<DatabaseConnection, ServiceError> {
let url = try!(extras_service_url(db_path));
let client = try!(nanoipc::init_client::<DatabaseClient<_>>(&url));
Ok(client)
}
// for tests
pub fn run_worker(scope: &crossbeam::Scope, stop: Arc<AtomicBool>, socket_path: &str) {
let socket_path = socket_path.to_owned();
scope.spawn(move || {
let mut worker = nanoipc::Worker::new(&Arc::new(Database::new()));
worker.add_reqrep(&socket_path).unwrap();
while !stop.load(Ordering::Relaxed) {
worker.poll();
}
});
}

View File

View File

@ -1,21 +1,38 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd.
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//! Ethcore database trait //! Ethcore database trait
use ipc::BinaryConvertable;
use std::mem; use std::mem;
use ipc::binary::BinaryConvertError; use ipc::binary::BinaryConvertError;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::cell::RefCell;
pub type TransactionHandle = u32;
pub type IteratorHandle = u32; pub type IteratorHandle = u32;
pub const DEFAULT_CACHE_LEN: usize = 12288;
#[derive(Binary)] #[derive(Binary)]
pub struct KeyValue { pub struct KeyValue {
pub key: Vec<u8>, pub key: Vec<u8>,
pub value: Vec<u8>, pub value: Vec<u8>,
} }
#[derive(Debug, Binary)] #[derive(Debug, Binary)]
pub enum Error { pub enum Error {
AlreadyOpen, AlreadyOpen,
IsClosed, IsClosed,
RocksDb(String), RocksDb(String),
@ -28,13 +45,36 @@ pub enum Error {
#[derive(Binary)] #[derive(Binary)]
pub struct DatabaseConfig { pub struct DatabaseConfig {
/// Optional prefix size in bytes. Allows lookup by partial key. /// Optional prefix size in bytes. Allows lookup by partial key.
pub prefix_size: Option<usize> pub prefix_size: Option<usize>,
/// write cache length
pub cache: usize,
} }
pub trait DatabaseService { impl Default for DatabaseConfig {
fn default() -> DatabaseConfig {
DatabaseConfig {
prefix_size: None,
cache: DEFAULT_CACHE_LEN,
}
}
}
impl DatabaseConfig {
fn with_prefix(prefix: usize) -> DatabaseConfig {
DatabaseConfig {
prefix_size: Some(prefix),
cache: DEFAULT_CACHE_LEN,
}
}
}
pub trait DatabaseService : Sized {
/// Opens database in the specified path /// Opens database in the specified path
fn open(&self, config: DatabaseConfig, path: String) -> Result<(), Error>; fn open(&self, config: DatabaseConfig, path: String) -> Result<(), Error>;
/// Opens database in the specified path with the default config
fn open_default(&self, path: String) -> Result<(), Error>;
/// Closes database /// Closes database
fn close(&self) -> Result<(), Error>; fn close(&self) -> Result<(), Error>;
@ -44,18 +84,6 @@ pub trait DatabaseService {
/// Delete value by key. /// Delete value by key.
fn delete(&self, key: &[u8]) -> Result<(), Error>; fn delete(&self, key: &[u8]) -> Result<(), Error>;
/// Insert a key-value pair in the transaction. Any existing value value will be overwritten.
fn transaction_put(&self, transaction: TransactionHandle, key: &[u8], value: &[u8]) -> Result<(), Error>;
/// Delete value by key using transaction
fn transaction_delete(&self, transaction: TransactionHandle, key: &[u8]) -> Result<(), Error>;
/// Commit transaction to database.
fn write(&self, tr: TransactionHandle) -> Result<(), Error>;
/// Initiate new transaction on database
fn new_transaction(&self) -> TransactionHandle;
/// Get value by key. /// Get value by key.
fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error>; fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error>;
@ -70,4 +98,35 @@ pub trait DatabaseService {
/// Next key-value for the the given iterator /// Next key-value for the the given iterator
fn iter_next(&self, iterator: IteratorHandle) -> Option<KeyValue>; fn iter_next(&self, iterator: IteratorHandle) -> Option<KeyValue>;
/// Dispose iteration that is no longer needed
fn dispose_iter(&self, handle: IteratorHandle) -> Result<(), Error>;
/// Write client transaction
fn write(&self, transaction: DBTransaction) -> Result<(), Error>;
}
#[derive(Binary)]
pub struct DBTransaction {
pub writes: RefCell<Vec<KeyValue>>,
pub removes: RefCell<Vec<Vec<u8>>>,
}
impl DBTransaction {
pub fn new() -> DBTransaction {
DBTransaction {
writes: RefCell::new(Vec::new()),
removes: RefCell::new(Vec::new()),
}
}
pub fn put(&self, key: &[u8], value: &[u8]) {
let mut brw = self.writes.borrow_mut();
brw.push(KeyValue { key: key.to_vec(), value: value.to_vec() });
}
pub fn delete(&self, key: &[u8]) {
let mut brw = self.removes.borrow_mut();
brw.push(key.to_vec());
}
} }

View File

@ -261,7 +261,7 @@ mod tests {
let mut db = MemoryDB::new(); let mut db = MemoryDB::new();
let mut db = AccountDBMut::new(&mut db, &Address::new()); let mut db = AccountDBMut::new(&mut db, &Address::new());
let rlp = { let rlp = {
let mut a = Account::new_contract(x!(69), x!(0)); let mut a = Account::new_contract(69.into(), 0.into());
a.set_storage(H256::from(&U256::from(0x00u64)), H256::from(&U256::from(0x1234u64))); a.set_storage(H256::from(&U256::from(0x00u64)), H256::from(&U256::from(0x1234u64)));
a.commit_storage(&mut db); a.commit_storage(&mut db);
a.init_code(vec![]); a.init_code(vec![]);
@ -281,7 +281,7 @@ mod tests {
let mut db = AccountDBMut::new(&mut db, &Address::new()); let mut db = AccountDBMut::new(&mut db, &Address::new());
let rlp = { let rlp = {
let mut a = Account::new_contract(x!(69), x!(0)); let mut a = Account::new_contract(69.into(), 0.into());
a.init_code(vec![0x55, 0x44, 0xffu8]); a.init_code(vec![0x55, 0x44, 0xffu8]);
a.commit_code(&mut db); a.commit_code(&mut db);
a.rlp() a.rlp()
@ -296,10 +296,10 @@ mod tests {
#[test] #[test]
fn commit_storage() { fn commit_storage() {
let mut a = Account::new_contract(x!(69), x!(0)); let mut a = Account::new_contract(69.into(), 0.into());
let mut db = MemoryDB::new(); let mut db = MemoryDB::new();
let mut db = AccountDBMut::new(&mut db, &Address::new()); let mut db = AccountDBMut::new(&mut db, &Address::new());
a.set_storage(x!(0), x!(0x1234)); a.set_storage(0.into(), 0x1234.into());
assert_eq!(a.storage_root(), None); assert_eq!(a.storage_root(), None);
a.commit_storage(&mut db); a.commit_storage(&mut db);
assert_eq!(a.storage_root().unwrap().hex(), "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2"); assert_eq!(a.storage_root().unwrap().hex(), "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2");
@ -307,21 +307,21 @@ mod tests {
#[test] #[test]
fn commit_remove_commit_storage() { fn commit_remove_commit_storage() {
let mut a = Account::new_contract(x!(69), x!(0)); let mut a = Account::new_contract(69.into(), 0.into());
let mut db = MemoryDB::new(); let mut db = MemoryDB::new();
let mut db = AccountDBMut::new(&mut db, &Address::new()); let mut db = AccountDBMut::new(&mut db, &Address::new());
a.set_storage(x!(0), x!(0x1234)); a.set_storage(0.into(), 0x1234.into());
a.commit_storage(&mut db); a.commit_storage(&mut db);
a.set_storage(x!(1), x!(0x1234)); a.set_storage(1.into(), 0x1234.into());
a.commit_storage(&mut db); a.commit_storage(&mut db);
a.set_storage(x!(1), x!(0)); a.set_storage(1.into(), 0.into());
a.commit_storage(&mut db); a.commit_storage(&mut db);
assert_eq!(a.storage_root().unwrap().hex(), "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2"); assert_eq!(a.storage_root().unwrap().hex(), "c57e1afb758b07f8d2c8f13a3b6e44fa5ff94ab266facc5a4fd3f062426e50b2");
} }
#[test] #[test]
fn commit_code() { fn commit_code() {
let mut a = Account::new_contract(x!(69), x!(0)); let mut a = Account::new_contract(69.into(), 0.into());
let mut db = MemoryDB::new(); let mut db = MemoryDB::new();
let mut db = AccountDBMut::new(&mut db, &Address::new()); let mut db = AccountDBMut::new(&mut db, &Address::new());
a.init_code(vec![0x55, 0x44, 0xffu8]); a.init_code(vec![0x55, 0x44, 0xffu8]);

View File

@ -20,7 +20,7 @@ impl<'db> AccountDB<'db> {
pub fn new(db: &'db HashDB, address: &Address) -> AccountDB<'db> { pub fn new(db: &'db HashDB, address: &Address) -> AccountDB<'db> {
AccountDB { AccountDB {
db: db, db: db,
address: x!(address), address: address.into(),
} }
} }
} }
@ -67,7 +67,7 @@ impl<'db> AccountDBMut<'db> {
pub fn new(db: &'db mut HashDB, address: &Address) -> AccountDBMut<'db> { pub fn new(db: &'db mut HashDB, address: &Address) -> AccountDBMut<'db> {
AccountDBMut { AccountDBMut {
db: db, db: db,
address: x!(address), address: address.into(),
} }
} }

View File

@ -86,9 +86,9 @@ impl Engine for BasicAuthority {
let gas_limit = parent.gas_limit; let gas_limit = parent.gas_limit;
let bound_divisor = self.our_params.gas_limit_bound_divisor; let bound_divisor = self.our_params.gas_limit_bound_divisor;
if gas_limit < gas_floor_target { if gas_limit < gas_floor_target {
min(gas_floor_target, gas_limit + gas_limit / bound_divisor - x!(1)) min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into())
} else { } else {
max(gas_floor_target, gas_limit - gas_limit / bound_divisor + x!(1)) max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into())
} }
}; };
header.note_dirty(); header.note_dirty();
@ -211,12 +211,12 @@ mod tests {
let engine = new_test_authority().engine; let engine = new_test_authority().engine;
let schedule = engine.schedule(&EnvInfo { let schedule = engine.schedule(&EnvInfo {
number: 10000000, number: 10000000,
author: x!(0), author: 0.into(),
timestamp: 0, timestamp: 0,
difficulty: x!(0), difficulty: 0.into(),
last_hashes: vec![], last_hashes: vec![],
gas_used: x!(0), gas_used: 0.into(),
gas_limit: x!(0) gas_limit: 0.into()
}); });
assert!(schedule.stack_limit > 0); assert!(schedule.stack_limit > 0);
@ -278,7 +278,7 @@ mod tests {
spec.ensure_db_good(db.as_hashdb_mut()); spec.ensure_db_good(db.as_hashdb_mut());
let last_hashes = vec![genesis_header.hash()]; let last_hashes = vec![genesis_header.hash()];
let vm_factory = Default::default(); let vm_factory = Default::default();
let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, addr.clone(), x!(3141562), vec![]); let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, addr.clone(), 3141562.into(), vec![]);
let b = b.close_and_lock(); let b = b.close_and_lock();
let seal = engine.generate_seal(b.block(), Some(&tap)).unwrap(); let seal = engine.generate_seal(b.block(), Some(&tap)).unwrap();

View File

@ -469,7 +469,7 @@ pub fn enact(header: &Header, transactions: &[SignedTransaction], uncles: &[Head
} }
} }
let mut b = OpenBlock::new(engine, vm_factory, tracing, db, parent, last_hashes, header.author().clone(), x!(3141562), header.extra_data().clone()); let mut b = OpenBlock::new(engine, vm_factory, tracing, db, parent, last_hashes, header.author().clone(), 3141562.into(), header.extra_data().clone());
b.set_difficulty(*header.difficulty()); b.set_difficulty(*header.difficulty());
b.set_gas_limit(*header.gas_limit()); b.set_gas_limit(*header.gas_limit());
b.set_timestamp(header.timestamp()); b.set_timestamp(header.timestamp());
@ -514,7 +514,7 @@ mod tests {
spec.ensure_db_good(db.as_hashdb_mut()); spec.ensure_db_good(db.as_hashdb_mut());
let last_hashes = vec![genesis_header.hash()]; let last_hashes = vec![genesis_header.hash()];
let vm_factory = Default::default(); let vm_factory = Default::default();
let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, Address::zero(), x!(3141562), vec![]); let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, Address::zero(), 3141562.into(), vec![]);
let b = b.close_and_lock(); let b = b.close_and_lock();
let _ = b.seal(engine.deref(), vec![]); let _ = b.seal(engine.deref(), vec![]);
} }
@ -530,7 +530,7 @@ mod tests {
let mut db = db_result.take(); let mut db = db_result.take();
spec.ensure_db_good(db.as_hashdb_mut()); spec.ensure_db_good(db.as_hashdb_mut());
let vm_factory = Default::default(); let vm_factory = Default::default();
let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, vec![genesis_header.hash()], Address::zero(), x!(3141562), vec![]).close_and_lock().seal(engine.deref(), vec![]).unwrap(); let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, vec![genesis_header.hash()], Address::zero(), 3141562.into(), vec![]).close_and_lock().seal(engine.deref(), vec![]).unwrap();
let orig_bytes = b.rlp_bytes(); let orig_bytes = b.rlp_bytes();
let orig_db = b.drain(); let orig_db = b.drain();
@ -557,7 +557,7 @@ mod tests {
let mut db = db_result.take(); let mut db = db_result.take();
spec.ensure_db_good(db.as_hashdb_mut()); spec.ensure_db_good(db.as_hashdb_mut());
let vm_factory = Default::default(); let vm_factory = Default::default();
let mut open_block = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, vec![genesis_header.hash()], Address::zero(), x!(3141562), vec![]); let mut open_block = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, vec![genesis_header.hash()], Address::zero(), 3141562.into(), vec![]);
let mut uncle1_header = Header::new(); let mut uncle1_header = Header::new();
uncle1_header.extra_data = b"uncle1".to_vec(); uncle1_header.extra_data = b"uncle1".to_vec();
let mut uncle2_header = Header::new(); let mut uncle2_header = Header::new();

View File

@ -311,17 +311,17 @@ impl BlockQueue {
let h = header.hash(); let h = header.hash();
{ {
if self.processing.read().unwrap().contains(&h) { if self.processing.read().unwrap().contains(&h) {
return Err(x!(ImportError::AlreadyQueued)); return Err(ImportError::AlreadyQueued.into());
} }
let mut bad = self.verification.bad.lock().unwrap(); let mut bad = self.verification.bad.lock().unwrap();
if bad.contains(&h) { if bad.contains(&h) {
return Err(x!(ImportError::KnownBad)); return Err(ImportError::KnownBad.into());
} }
if bad.contains(&header.parent_hash) { if bad.contains(&header.parent_hash) {
bad.insert(h.clone()); bad.insert(h.clone());
return Err(x!(ImportError::KnownBad)); return Err(ImportError::KnownBad.into());
} }
} }

View File

@ -599,10 +599,10 @@ impl<V> BlockChainClient for Client<V> where V: Verifier {
{ {
let header = BlockView::new(&bytes).header_view(); let header = BlockView::new(&bytes).header_view();
if self.chain.is_known(&header.sha3()) { if self.chain.is_known(&header.sha3()) {
return Err(x!(ImportError::AlreadyInChain)); return Err(ImportError::AlreadyInChain.into());
} }
if self.block_status(BlockID::Hash(header.parent_hash())) == BlockStatus::Unknown { if self.block_status(BlockID::Hash(header.parent_hash())) == BlockStatus::Unknown {
return Err(x!(BlockError::UnknownParent(header.parent_hash()))); return Err(BlockError::UnknownParent(header.parent_hash()).into());
} }
} }
self.block_queue.import_block(bytes) self.block_queue.import_block(bytes)

View File

@ -47,10 +47,10 @@ impl Default for EnvInfo {
number: 0, number: 0,
author: Address::new(), author: Address::new(),
timestamp: 0, timestamp: 0,
difficulty: x!(0), difficulty: 0.into(),
gas_limit: x!(0), gas_limit: 0.into(),
last_hashes: vec![], last_hashes: vec![],
gas_used: x!(0), gas_used: 0.into(),
} }
} }
} }
@ -92,15 +92,15 @@ mod tests {
assert_eq!(env_info.number, 1112339); assert_eq!(env_info.number, 1112339);
assert_eq!(env_info.author, Address::from_str("000000f00000000f000000000000f00000000f00").unwrap()); assert_eq!(env_info.author, Address::from_str("000000f00000000f000000000000f00000000f00").unwrap());
assert_eq!(env_info.gas_limit, x!(40000)); assert_eq!(env_info.gas_limit, 40000.into());
assert_eq!(env_info.difficulty, x!(50000)); assert_eq!(env_info.difficulty, 50000.into());
assert_eq!(env_info.gas_used, x!(0)); assert_eq!(env_info.gas_used, 0.into());
} }
#[test] #[test]
fn it_can_be_created_as_default() { fn it_can_be_created_as_default() {
let default_env_info = EnvInfo::default(); let default_env_info = EnvInfo::default();
assert_eq!(default_env_info.difficulty, x!(0)); assert_eq!(default_env_info.difficulty, 0.into());
} }
} }

View File

@ -111,9 +111,9 @@ impl Engine for Ethash {
let gas_limit = parent.gas_limit; let gas_limit = parent.gas_limit;
let bound_divisor = self.ethash_params.gas_limit_bound_divisor; let bound_divisor = self.ethash_params.gas_limit_bound_divisor;
if gas_limit < gas_floor_target { if gas_limit < gas_floor_target {
min(gas_floor_target, gas_limit + gas_limit / bound_divisor - x!(1)) min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into())
} else { } else {
max(gas_floor_target, gas_limit - gas_limit / bound_divisor + x!(1) + (header.gas_used * x!(6) / x!(5)) / bound_divisor) max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into() + (header.gas_used * 6.into() / 5.into()) / bound_divisor)
} }
}; };
header.note_dirty(); header.note_dirty();
@ -255,12 +255,12 @@ impl Ethash {
/// Convert an Ethash boundary to its original difficulty. Basically just `f(x) = 2^256 / x`. /// Convert an Ethash boundary to its original difficulty. Basically just `f(x) = 2^256 / x`.
pub fn boundary_to_difficulty(boundary: &H256) -> U256 { pub fn boundary_to_difficulty(boundary: &H256) -> U256 {
U256::from((U512::one() << 256) / x!(U256::from(boundary.as_slice()))) U256::from((U512::one() << 256) / U256::from(boundary.as_slice()).into())
} }
/// Convert an Ethash difficulty to the target boundary. Basically just `f(x) = 2^256 / x`. /// Convert an Ethash difficulty to the target boundary. Basically just `f(x) = 2^256 / x`.
pub fn difficulty_to_boundary(difficulty: &U256) -> H256 { pub fn difficulty_to_boundary(difficulty: &U256) -> H256 {
x!(U256::from((U512::one() << 256) / x!(difficulty))) U256::from((U512::one() << 256) / difficulty.into()).into()
} }
fn to_ethash(hash: H256) -> EH256 { fn to_ethash(hash: H256) -> EH256 {
@ -308,7 +308,7 @@ mod tests {
spec.ensure_db_good(db.as_hashdb_mut()); spec.ensure_db_good(db.as_hashdb_mut());
let last_hashes = vec![genesis_header.hash()]; let last_hashes = vec![genesis_header.hash()];
let vm_factory = Default::default(); let vm_factory = Default::default();
let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, Address::zero(), x!(3141562), vec![]); let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, Address::zero(), 3141562.into(), vec![]);
let b = b.close(); let b = b.close();
assert_eq!(b.state().balance(&Address::zero()), U256::from_str("4563918244f40000").unwrap()); assert_eq!(b.state().balance(&Address::zero()), U256::from_str("4563918244f40000").unwrap());
} }
@ -323,7 +323,7 @@ mod tests {
spec.ensure_db_good(db.as_hashdb_mut()); spec.ensure_db_good(db.as_hashdb_mut());
let last_hashes = vec![genesis_header.hash()]; let last_hashes = vec![genesis_header.hash()];
let vm_factory = Default::default(); let vm_factory = Default::default();
let mut b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, Address::zero(), x!(3141562), vec![]); let mut b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, Address::zero(), 3141562.into(), vec![]);
let mut uncle = Header::new(); let mut uncle = Header::new();
let uncle_author = address_from_hex("ef2d6d194084c2de36e0dabfce45d046b37d1106"); let uncle_author = address_from_hex("ef2d6d194084c2de36e0dabfce45d046b37d1106");
uncle.author = uncle_author.clone(); uncle.author = uncle_author.clone();
@ -346,24 +346,24 @@ mod tests {
let engine = new_morden().engine; let engine = new_morden().engine;
let schedule = engine.schedule(&EnvInfo { let schedule = engine.schedule(&EnvInfo {
number: 10000000, number: 10000000,
author: x!(0), author: 0.into(),
timestamp: 0, timestamp: 0,
difficulty: x!(0), difficulty: 0.into(),
last_hashes: vec![], last_hashes: vec![],
gas_used: x!(0), gas_used: 0.into(),
gas_limit: x!(0) gas_limit: 0.into()
}); });
assert!(schedule.stack_limit > 0); assert!(schedule.stack_limit > 0);
let schedule = engine.schedule(&EnvInfo { let schedule = engine.schedule(&EnvInfo {
number: 100, number: 100,
author: x!(0), author: 0.into(),
timestamp: 0, timestamp: 0,
difficulty: x!(0), difficulty: 0.into(),
last_hashes: vec![], last_hashes: vec![],
gas_used: x!(0), gas_used: 0.into(),
gas_limit: x!(0) gas_limit: 0.into()
}); });
assert!(!schedule.have_delegate_call); assert!(!schedule.have_delegate_call);

View File

@ -361,7 +361,7 @@ impl<'a> Executive<'a> {
let refunds_bound = sstore_refunds + suicide_refunds; let refunds_bound = sstore_refunds + suicide_refunds;
// real ammount to refund // real ammount to refund
let gas_left_prerefund = match result { Ok(x) => x, _ => x!(0) }; let gas_left_prerefund = match result { Ok(x) => x, _ => 0.into() };
let refunded = cmp::min(refunds_bound, (t.gas - gas_left_prerefund) / U256::from(2)); let refunded = cmp::min(refunds_bound, (t.gas - gas_left_prerefund) / U256::from(2));
let gas_left = gas_left_prerefund + refunded; let gas_left = gas_left_prerefund + refunded;
@ -588,10 +588,10 @@ mod tests {
let expected_trace = vec![ Trace { let expected_trace = vec![ Trace {
depth: 0, depth: 0,
action: trace::Action::Call(trace::Call { action: trace::Action::Call(trace::Call {
from: x!("cd1722f3947def4cf144679da39c4c32bdc35681"), from: "cd1722f3947def4cf144679da39c4c32bdc35681".into(),
to: x!("b010143a42d5980c7e5ef0e4a4416dc098a4fed3"), to: "b010143a42d5980c7e5ef0e4a4416dc098a4fed3".into(),
value: x!(100), value: 100.into(),
gas: x!(100000), gas: 100000.into(),
input: vec![], input: vec![],
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
@ -601,9 +601,9 @@ mod tests {
subs: vec![Trace { subs: vec![Trace {
depth: 1, depth: 1,
action: trace::Action::Create(trace::Create { action: trace::Action::Create(trace::Create {
from: x!("b010143a42d5980c7e5ef0e4a4416dc098a4fed3"), from: "b010143a42d5980c7e5ef0e4a4416dc098a4fed3".into(),
value: x!(23), value: 23.into(),
gas: x!(67979), gas: 67979.into(),
init: vec![96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85] init: vec![96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85]
}), }),
result: trace::Res::Create(trace::CreateResult { result: trace::Res::Create(trace::CreateResult {
@ -642,7 +642,7 @@ mod tests {
params.origin = sender.clone(); params.origin = sender.clone();
params.gas = U256::from(100_000); params.gas = U256::from(100_000);
params.code = Some(code.clone()); params.code = Some(code.clone());
params.value = ActionValue::Transfer(x!(100)); params.value = ActionValue::Transfer(100.into());
let mut state_result = get_temp_state(); let mut state_result = get_temp_state();
let mut state = state_result.reference_mut(); let mut state = state_result.reference_mut();
state.add_balance(&sender, &U256::from(100)); state.add_balance(&sender, &U256::from(100));
@ -660,7 +660,7 @@ mod tests {
depth: 0, depth: 0,
action: trace::Action::Create(trace::Create { action: trace::Action::Create(trace::Create {
from: params.sender, from: params.sender,
value: x!(100), value: 100.into(),
gas: params.gas, gas: params.gas,
init: vec![96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85], init: vec![96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85],
}), }),

View File

@ -311,12 +311,12 @@ mod tests {
fn get_test_env_info() -> EnvInfo { fn get_test_env_info() -> EnvInfo {
EnvInfo { EnvInfo {
number: 100, number: 100,
author: x!(0), author: 0.into(),
timestamp: 0, timestamp: 0,
difficulty: x!(0), difficulty: 0.into(),
last_hashes: vec![], last_hashes: vec![],
gas_used: x!(0), gas_used: 0.into(),
gas_limit: x!(0) gas_limit: 0.into()
} }
} }

View File

@ -137,7 +137,7 @@ impl Miner {
Err(Error::Execution(ExecutionError::BlockGasLimitReached { gas_limit, gas_used, .. })) => { Err(Error::Execution(ExecutionError::BlockGasLimitReached { gas_limit, gas_used, .. })) => {
trace!(target: "miner", "Skipping adding transaction to block because of gas limit: {:?}", hash); trace!(target: "miner", "Skipping adding transaction to block because of gas limit: {:?}", hash);
// Exit early if gas left is smaller then min_tx_gas // Exit early if gas left is smaller then min_tx_gas
let min_tx_gas: U256 = x!(21000); // TODO: figure this out properly. let min_tx_gas: U256 = 21000.into(); // TODO: figure this out properly.
if gas_limit - gas_used < min_tx_gas { if gas_limit - gas_used < min_tx_gas {
break; break;
} }
@ -337,11 +337,11 @@ impl MinerService for Miner {
fn sensible_gas_price(&self) -> U256 { fn sensible_gas_price(&self) -> U256 {
// 10% above our minimum. // 10% above our minimum.
*self.transaction_queue.lock().unwrap().minimal_gas_price() * x!(110) / x!(100) *self.transaction_queue.lock().unwrap().minimal_gas_price() * 110.into() / 100.into()
} }
fn sensible_gas_limit(&self) -> U256 { fn sensible_gas_limit(&self) -> U256 {
*self.gas_floor_target.read().unwrap() / x!(5) *self.gas_floor_target.read().unwrap() / 5.into()
} }
fn transactions_limit(&self) -> usize { fn transactions_limit(&self) -> usize {

View File

@ -140,10 +140,10 @@ pub trait MinerService : Send + Sync {
fn last_nonce(&self, address: &Address) -> Option<U256>; fn last_nonce(&self, address: &Address) -> Option<U256>;
/// Suggested gas price. /// Suggested gas price.
fn sensible_gas_price(&self) -> U256 { x!(20000000000u64) } fn sensible_gas_price(&self) -> U256 { 20000000000u64.into() }
/// Suggested gas limit. /// Suggested gas limit.
fn sensible_gas_limit(&self) -> U256 { x!(21000) } fn sensible_gas_limit(&self) -> U256 { 21000.into() }
/// Latest account balance in pending state. /// Latest account balance in pending state.
fn balance(&self, chain: &MiningBlockChainClient, address: &Address) -> U256; fn balance(&self, chain: &MiningBlockChainClient, address: &Address) -> U256;

View File

@ -114,11 +114,11 @@ mod test {
#[test] #[test]
fn existence() { fn existence() {
let a = PodAccount{balance: x!(69), nonce: x!(0), code: vec![], storage: map![]}; let a = PodAccount{balance: 69.into(), nonce: 0.into(), code: vec![], storage: map![]};
assert_eq!(AccountDiff::diff_pod(Some(&a), Some(&a)), None); assert_eq!(AccountDiff::diff_pod(Some(&a), Some(&a)), None);
assert_eq!(AccountDiff::diff_pod(None, Some(&a)), Some(AccountDiff{ assert_eq!(AccountDiff::diff_pod(None, Some(&a)), Some(AccountDiff{
balance: Diff::Born(x!(69)), balance: Diff::Born(69.into()),
nonce: Diff::Born(x!(0)), nonce: Diff::Born(0.into()),
code: Diff::Born(vec![]), code: Diff::Born(vec![]),
storage: map![], storage: map![],
})); }));
@ -126,11 +126,11 @@ mod test {
#[test] #[test]
fn basic() { fn basic() {
let a = PodAccount{balance: x!(69), nonce: x!(0), code: vec![], storage: map![]}; let a = PodAccount{balance: 69.into(), nonce: 0.into(), code: vec![], storage: map![]};
let b = PodAccount{balance: x!(42), nonce: x!(1), code: vec![], storage: map![]}; let b = PodAccount{balance: 42.into(), nonce: 1.into(), code: vec![], storage: map![]};
assert_eq!(AccountDiff::diff_pod(Some(&a), Some(&b)), Some(AccountDiff { assert_eq!(AccountDiff::diff_pod(Some(&a), Some(&b)), Some(AccountDiff {
balance: Diff::Changed(x!(69), x!(42)), balance: Diff::Changed(69.into(), 42.into()),
nonce: Diff::Changed(x!(0), x!(1)), nonce: Diff::Changed(0.into(), 1.into()),
code: Diff::Same, code: Diff::Same,
storage: map![], storage: map![],
})); }));
@ -138,11 +138,11 @@ mod test {
#[test] #[test]
fn code() { fn code() {
let a = PodAccount{balance: x!(0), nonce: x!(0), code: vec![], storage: map![]}; let a = PodAccount{balance: 0.into(), nonce: 0.into(), code: vec![], storage: map![]};
let b = PodAccount{balance: x!(0), nonce: x!(1), code: vec![0], storage: map![]}; let b = PodAccount{balance: 0.into(), nonce: 1.into(), code: vec![0], storage: map![]};
assert_eq!(AccountDiff::diff_pod(Some(&a), Some(&b)), Some(AccountDiff { assert_eq!(AccountDiff::diff_pod(Some(&a), Some(&b)), Some(AccountDiff {
balance: Diff::Same, balance: Diff::Same,
nonce: Diff::Changed(x!(0), x!(1)), nonce: Diff::Changed(0.into(), 1.into()),
code: Diff::Changed(vec![], vec![0]), code: Diff::Changed(vec![], vec![0]),
storage: map![], storage: map![],
})); }));
@ -151,27 +151,27 @@ mod test {
#[test] #[test]
fn storage() { fn storage() {
let a = PodAccount { let a = PodAccount {
balance: x!(0), balance: 0.into(),
nonce: x!(0), nonce: 0.into(),
code: vec![], code: vec![],
storage: mapx![1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 0, 6 => 0, 7 => 0] storage: map_into![1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 0, 6 => 0, 7 => 0]
}; };
let b = PodAccount { let b = PodAccount {
balance: x!(0), balance: 0.into(),
nonce: x!(0), nonce: 0.into(),
code: vec![], code: vec![],
storage: mapx![1 => 1, 2 => 3, 3 => 0, 5 => 0, 7 => 7, 8 => 0, 9 => 9] storage: map_into![1 => 1, 2 => 3, 3 => 0, 5 => 0, 7 => 7, 8 => 0, 9 => 9]
}; };
assert_eq!(AccountDiff::diff_pod(Some(&a), Some(&b)), Some(AccountDiff { assert_eq!(AccountDiff::diff_pod(Some(&a), Some(&b)), Some(AccountDiff {
balance: Diff::Same, balance: Diff::Same,
nonce: Diff::Same, nonce: Diff::Same,
code: Diff::Same, code: Diff::Same,
storage: map![ storage: map![
x!(2) => Diff::new(x!(2), x!(3)), 2.into() => Diff::new(2.into(), 3.into()),
x!(3) => Diff::new(x!(3), x!(0)), 3.into() => Diff::new(3.into(), 0.into()),
x!(4) => Diff::new(x!(4), x!(0)), 4.into() => Diff::new(4.into(), 0.into()),
x!(7) => Diff::new(x!(0), x!(7)), 7.into() => Diff::new(0.into(), 7.into()),
x!(9) => Diff::new(x!(0), x!(9)) 9.into() => Diff::new(0.into(), 9.into())
], ],
})); }));
} }

View File

@ -214,7 +214,7 @@ impl State {
/// Initialise the code of account `a` so that it is `value` for `key`. /// Initialise the code of account `a` so that it is `value` for `key`.
/// NOTE: Account should have been created with `new_contract`. /// NOTE: Account should have been created with `new_contract`.
pub fn init_code(&mut self, a: &Address, code: Bytes) { pub fn init_code(&mut self, a: &Address, code: Bytes) {
self.require_or_from(a, true, || Account::new_contract(x!(0), self.account_start_nonce), |_|{}).init_code(code); self.require_or_from(a, true, || Account::new_contract(0.into(), self.account_start_nonce), |_|{}).init_code(code);
} }
/// Execute a given transaction. /// Execute a given transaction.
@ -377,27 +377,27 @@ fn should_apply_create_transaction() {
let mut state = get_temp_state_in(temp.as_path()); let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = x!(1_000_000); info.gas_limit = 1_000_000.into();
let engine = TestEngine::new(5); let engine = TestEngine::new(5);
let t = Transaction { let t = Transaction {
nonce: x!(0), nonce: 0.into(),
gas_price: x!(0), gas_price: 0.into(),
gas: x!(100_000), gas: 100_000.into(),
action: Action::Create, action: Action::Create,
value: x!(100), value: 100.into(),
data: FromHex::from_hex("601080600c6000396000f3006000355415600957005b60203560003555").unwrap(), data: FromHex::from_hex("601080600c6000396000f3006000355415600957005b60203560003555").unwrap(),
}.sign(&"".sha3()); }.sign(&"".sha3());
state.add_balance(t.sender().as_ref().unwrap(), &x!(100)); state.add_balance(t.sender().as_ref().unwrap(), &(100.into()));
let vm_factory = Default::default(); let vm_factory = Default::default();
let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap(); let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap();
let expected_trace = Some(Trace { let expected_trace = Some(Trace {
depth: 0, depth: 0,
action: trace::Action::Create(trace::Create { action: trace::Action::Create(trace::Create {
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"), from: "9cce34f7ab185c7aba1b7c8140d620b4bda941d6".into(),
value: x!(100), value: 100.into(),
gas: x!(77412), gas: 77412.into(),
init: vec![96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85], init: vec![96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85],
}), }),
result: trace::Res::Create(trace::CreateResult { result: trace::Res::Create(trace::CreateResult {
@ -438,27 +438,27 @@ fn should_trace_failed_create_transaction() {
let mut state = get_temp_state_in(temp.as_path()); let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = x!(1_000_000); info.gas_limit = 1_000_000.into();
let engine = TestEngine::new(5); let engine = TestEngine::new(5);
let t = Transaction { let t = Transaction {
nonce: x!(0), nonce: 0.into(),
gas_price: x!(0), gas_price: 0.into(),
gas: x!(100_000), gas: 100_000.into(),
action: Action::Create, action: Action::Create,
value: x!(100), value: 100.into(),
data: FromHex::from_hex("5b600056").unwrap(), data: FromHex::from_hex("5b600056").unwrap(),
}.sign(&"".sha3()); }.sign(&"".sha3());
state.add_balance(t.sender().as_ref().unwrap(), &x!(100)); state.add_balance(t.sender().as_ref().unwrap(), &(100.into()));
let vm_factory = Default::default(); let vm_factory = Default::default();
let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap(); let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap();
let expected_trace = Some(Trace { let expected_trace = Some(Trace {
depth: 0, depth: 0,
action: trace::Action::Create(trace::Create { action: trace::Action::Create(trace::Create {
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"), from: "9cce34f7ab185c7aba1b7c8140d620b4bda941d6".into(),
value: x!(100), value: 100.into(),
gas: x!(78792), gas: 78792.into(),
init: vec![91, 96, 0, 86], init: vec![91, 96, 0, 86],
}), }),
result: trace::Res::FailedCreate, result: trace::Res::FailedCreate,
@ -476,29 +476,29 @@ fn should_trace_call_transaction() {
let mut state = get_temp_state_in(temp.as_path()); let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = x!(1_000_000); info.gas_limit = 1_000_000.into();
let engine = TestEngine::new(5); let engine = TestEngine::new(5);
let t = Transaction { let t = Transaction {
nonce: x!(0), nonce: 0.into(),
gas_price: x!(0), gas_price: 0.into(),
gas: x!(100_000), gas: 100_000.into(),
action: Action::Call(x!(0xa)), action: Action::Call(0xa.into()),
value: x!(100), value: 100.into(),
data: vec![], data: vec![],
}.sign(&"".sha3()); }.sign(&"".sha3());
state.init_code(&x!(0xa), FromHex::from_hex("6000").unwrap()); state.init_code(&0xa.into(), FromHex::from_hex("6000").unwrap());
state.add_balance(t.sender().as_ref().unwrap(), &x!(100)); state.add_balance(t.sender().as_ref().unwrap(), &(100.into()));
let vm_factory = Default::default(); let vm_factory = Default::default();
let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap(); let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap();
let expected_trace = Some(Trace { let expected_trace = Some(Trace {
depth: 0, depth: 0,
action: trace::Action::Call(trace::Call { action: trace::Action::Call(trace::Call {
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"), from: "9cce34f7ab185c7aba1b7c8140d620b4bda941d6".into(),
to: x!(0xa), to: 0xa.into(),
value: x!(100), value: 100.into(),
gas: x!(79000), gas: 79000.into(),
input: vec![], input: vec![],
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
@ -519,28 +519,28 @@ fn should_trace_basic_call_transaction() {
let mut state = get_temp_state_in(temp.as_path()); let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = x!(1_000_000); info.gas_limit = 1_000_000.into();
let engine = TestEngine::new(5); let engine = TestEngine::new(5);
let t = Transaction { let t = Transaction {
nonce: x!(0), nonce: 0.into(),
gas_price: x!(0), gas_price: 0.into(),
gas: x!(100_000), gas: 100_000.into(),
action: Action::Call(x!(0xa)), action: Action::Call(0xa.into()),
value: x!(100), value: 100.into(),
data: vec![], data: vec![],
}.sign(&"".sha3()); }.sign(&"".sha3());
state.add_balance(t.sender().as_ref().unwrap(), &x!(100)); state.add_balance(t.sender().as_ref().unwrap(), &(100.into()));
let vm_factory = Default::default(); let vm_factory = Default::default();
let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap(); let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap();
let expected_trace = Some(Trace { let expected_trace = Some(Trace {
depth: 0, depth: 0,
action: trace::Action::Call(trace::Call { action: trace::Action::Call(trace::Call {
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"), from: "9cce34f7ab185c7aba1b7c8140d620b4bda941d6".into(),
to: x!(0xa), to: 0xa.into(),
value: x!(100), value: 100.into(),
gas: x!(79000), gas: 79000.into(),
input: vec![], input: vec![],
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
@ -561,15 +561,15 @@ fn should_trace_call_transaction_to_builtin() {
let mut state = get_temp_state_in(temp.as_path()); let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = x!(1_000_000); info.gas_limit = 1_000_000.into();
let engine = Spec::new_test().engine; let engine = Spec::new_test().engine;
let t = Transaction { let t = Transaction {
nonce: x!(0), nonce: 0.into(),
gas_price: x!(0), gas_price: 0.into(),
gas: x!(100_000), gas: 100_000.into(),
action: Action::Call(x!(0x1)), action: Action::Call(0x1.into()),
value: x!(0), value: 0.into(),
data: vec![], data: vec![],
}.sign(&"".sha3()); }.sign(&"".sha3());
@ -579,10 +579,10 @@ fn should_trace_call_transaction_to_builtin() {
assert_eq!(result.trace, Some(Trace { assert_eq!(result.trace, Some(Trace {
depth: 0, depth: 0,
action: trace::Action::Call(trace::Call { action: trace::Action::Call(trace::Call {
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"), from: "9cce34f7ab185c7aba1b7c8140d620b4bda941d6".into(),
to: x!("0000000000000000000000000000000000000001"), to: "0000000000000000000000000000000000000001".into(),
value: x!(0), value: 0.into(),
gas: x!(79_000), gas: 79_000.into(),
input: vec![], input: vec![],
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
@ -601,29 +601,29 @@ fn should_not_trace_subcall_transaction_to_builtin() {
let mut state = get_temp_state_in(temp.as_path()); let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = x!(1_000_000); info.gas_limit = 1_000_000.into();
let engine = Spec::new_test().engine; let engine = Spec::new_test().engine;
let t = Transaction { let t = Transaction {
nonce: x!(0), nonce: 0.into(),
gas_price: x!(0), gas_price: 0.into(),
gas: x!(100_000), gas: 100_000.into(),
action: Action::Call(x!(0xa)), action: Action::Call(0xa.into()),
value: x!(0), value: 0.into(),
data: vec![], data: vec![],
}.sign(&"".sha3()); }.sign(&"".sha3());
state.init_code(&x!(0xa), FromHex::from_hex("600060006000600060006001610be0f1").unwrap()); state.init_code(&0xa.into(), FromHex::from_hex("600060006000600060006001610be0f1").unwrap());
let vm_factory = Default::default(); let vm_factory = Default::default();
let result = state.apply(&info, engine.deref(), &vm_factory, &t, true).unwrap(); let result = state.apply(&info, engine.deref(), &vm_factory, &t, true).unwrap();
let expected_trace = Some(Trace { let expected_trace = Some(Trace {
depth: 0, depth: 0,
action: trace::Action::Call(trace::Call { action: trace::Action::Call(trace::Call {
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"), from: "9cce34f7ab185c7aba1b7c8140d620b4bda941d6".into(),
to: x!(0xa), to: 0xa.into(),
value: x!(0), value: 0.into(),
gas: x!(79000), gas: 79000.into(),
input: vec![], input: vec![],
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
@ -643,30 +643,30 @@ fn should_not_trace_callcode() {
let mut state = get_temp_state_in(temp.as_path()); let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = x!(1_000_000); info.gas_limit = 1_000_000.into();
let engine = Spec::new_test().engine; let engine = Spec::new_test().engine;
let t = Transaction { let t = Transaction {
nonce: x!(0), nonce: 0.into(),
gas_price: x!(0), gas_price: 0.into(),
gas: x!(100_000), gas: 100_000.into(),
action: Action::Call(x!(0xa)), action: Action::Call(0xa.into()),
value: x!(0), value: 0.into(),
data: vec![], data: vec![],
}.sign(&"".sha3()); }.sign(&"".sha3());
state.init_code(&x!(0xa), FromHex::from_hex("60006000600060006000600b611000f2").unwrap()); state.init_code(&0xa.into(), FromHex::from_hex("60006000600060006000600b611000f2").unwrap());
state.init_code(&x!(0xb), FromHex::from_hex("6000").unwrap()); state.init_code(&0xb.into(), FromHex::from_hex("6000").unwrap());
let vm_factory = Default::default(); let vm_factory = Default::default();
let result = state.apply(&info, engine.deref(), &vm_factory, &t, true).unwrap(); let result = state.apply(&info, engine.deref(), &vm_factory, &t, true).unwrap();
let expected_trace = Some(Trace { let expected_trace = Some(Trace {
depth: 0, depth: 0,
action: trace::Action::Call(trace::Call { action: trace::Action::Call(trace::Call {
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"), from: "9cce34f7ab185c7aba1b7c8140d620b4bda941d6".into(),
to: x!(0xa), to: 0xa.into(),
value: x!(0), value: 0.into(),
gas: x!(79000), gas: 79000.into(),
input: vec![], input: vec![],
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
@ -686,33 +686,33 @@ fn should_not_trace_delegatecall() {
let mut state = get_temp_state_in(temp.as_path()); let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = x!(1_000_000); info.gas_limit = 1_000_000.into();
info.number = 0x789b0; info.number = 0x789b0;
let engine = Spec::new_test().engine; let engine = Spec::new_test().engine;
println!("schedule.have_delegate_call: {:?}", engine.schedule(&info).have_delegate_call); println!("schedule.have_delegate_call: {:?}", engine.schedule(&info).have_delegate_call);
let t = Transaction { let t = Transaction {
nonce: x!(0), nonce: 0.into(),
gas_price: x!(0), gas_price: 0.into(),
gas: x!(100_000), gas: 100_000.into(),
action: Action::Call(x!(0xa)), action: Action::Call(0xa.into()),
value: x!(0), value: 0.into(),
data: vec![], data: vec![],
}.sign(&"".sha3()); }.sign(&"".sha3());
state.init_code(&x!(0xa), FromHex::from_hex("6000600060006000600b618000f4").unwrap()); state.init_code(&0xa.into(), FromHex::from_hex("6000600060006000600b618000f4").unwrap());
state.init_code(&x!(0xb), FromHex::from_hex("6000").unwrap()); state.init_code(&0xb.into(), FromHex::from_hex("6000").unwrap());
let vm_factory = Default::default(); let vm_factory = Default::default();
let result = state.apply(&info, engine.deref(), &vm_factory, &t, true).unwrap(); let result = state.apply(&info, engine.deref(), &vm_factory, &t, true).unwrap();
let expected_trace = Some(Trace { let expected_trace = Some(Trace {
depth: 0, depth: 0,
action: trace::Action::Call(trace::Call { action: trace::Action::Call(trace::Call {
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"), from: "9cce34f7ab185c7aba1b7c8140d620b4bda941d6".into(),
to: x!(0xa), to: 0xa.into(),
value: x!(0), value: 0.into(),
gas: x!(79000), gas: 79000.into(),
input: vec![], input: vec![],
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
@ -732,29 +732,29 @@ fn should_trace_failed_call_transaction() {
let mut state = get_temp_state_in(temp.as_path()); let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = x!(1_000_000); info.gas_limit = 1_000_000.into();
let engine = TestEngine::new(5); let engine = TestEngine::new(5);
let t = Transaction { let t = Transaction {
nonce: x!(0), nonce: 0.into(),
gas_price: x!(0), gas_price: 0.into(),
gas: x!(100_000), gas: 100_000.into(),
action: Action::Call(x!(0xa)), action: Action::Call(0xa.into()),
value: x!(100), value: 100.into(),
data: vec![], data: vec![],
}.sign(&"".sha3()); }.sign(&"".sha3());
state.init_code(&x!(0xa), FromHex::from_hex("5b600056").unwrap()); state.init_code(&0xa.into(), FromHex::from_hex("5b600056").unwrap());
state.add_balance(t.sender().as_ref().unwrap(), &x!(100)); state.add_balance(t.sender().as_ref().unwrap(), &(100.into()));
let vm_factory = Default::default(); let vm_factory = Default::default();
let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap(); let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap();
let expected_trace = Some(Trace { let expected_trace = Some(Trace {
depth: 0, depth: 0,
action: trace::Action::Call(trace::Call { action: trace::Action::Call(trace::Call {
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"), from: "9cce34f7ab185c7aba1b7c8140d620b4bda941d6".into(),
to: x!(0xa), to: 0xa.into(),
value: x!(100), value: 100.into(),
gas: x!(79000), gas: 79000.into(),
input: vec![], input: vec![],
}), }),
result: trace::Res::FailedCall, result: trace::Res::FailedCall,
@ -774,30 +774,30 @@ fn should_trace_call_with_subcall_transaction() {
let mut state = get_temp_state_in(temp.as_path()); let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = x!(1_000_000); info.gas_limit = 1_000_000.into();
let engine = TestEngine::new(5); let engine = TestEngine::new(5);
let t = Transaction { let t = Transaction {
nonce: x!(0), nonce: 0.into(),
gas_price: x!(0), gas_price: 0.into(),
gas: x!(100_000), gas: 100_000.into(),
action: Action::Call(x!(0xa)), action: Action::Call(0xa.into()),
value: x!(100), value: 100.into(),
data: vec![], data: vec![],
}.sign(&"".sha3()); }.sign(&"".sha3());
state.init_code(&x!(0xa), FromHex::from_hex("60006000600060006000600b602b5a03f1").unwrap()); state.init_code(&0xa.into(), FromHex::from_hex("60006000600060006000600b602b5a03f1").unwrap());
state.init_code(&x!(0xb), FromHex::from_hex("6000").unwrap()); state.init_code(&0xb.into(), FromHex::from_hex("6000").unwrap());
state.add_balance(t.sender().as_ref().unwrap(), &x!(100)); state.add_balance(t.sender().as_ref().unwrap(), &(100.into()));
let vm_factory = Default::default(); let vm_factory = Default::default();
let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap(); let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap();
let expected_trace = Some(Trace { let expected_trace = Some(Trace {
depth: 0, depth: 0,
action: trace::Action::Call(trace::Call { action: trace::Action::Call(trace::Call {
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"), from: "9cce34f7ab185c7aba1b7c8140d620b4bda941d6".into(),
to: x!(0xa), to: 0xa.into(),
value: x!(100), value: 100.into(),
gas: x!(79000), gas: 79000.into(),
input: vec![], input: vec![],
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
@ -807,10 +807,10 @@ fn should_trace_call_with_subcall_transaction() {
subs: vec![Trace { subs: vec![Trace {
depth: 1, depth: 1,
action: trace::Action::Call(trace::Call { action: trace::Action::Call(trace::Call {
from: x!(0xa), from: 0xa.into(),
to: x!(0xb), to: 0xb.into(),
value: x!(0), value: 0.into(),
gas: x!(78934), gas: 78934.into(),
input: vec![], input: vec![],
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
@ -832,29 +832,29 @@ fn should_trace_call_with_basic_subcall_transaction() {
let mut state = get_temp_state_in(temp.as_path()); let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = x!(1_000_000); info.gas_limit = 1_000_000.into();
let engine = TestEngine::new(5); let engine = TestEngine::new(5);
let t = Transaction { let t = Transaction {
nonce: x!(0), nonce: 0.into(),
gas_price: x!(0), gas_price: 0.into(),
gas: x!(100_000), gas: 100_000.into(),
action: Action::Call(x!(0xa)), action: Action::Call(0xa.into()),
value: x!(100), value: 100.into(),
data: vec![], data: vec![],
}.sign(&"".sha3()); }.sign(&"".sha3());
state.init_code(&x!(0xa), FromHex::from_hex("60006000600060006045600b6000f1").unwrap()); state.init_code(&0xa.into(), FromHex::from_hex("60006000600060006045600b6000f1").unwrap());
state.add_balance(t.sender().as_ref().unwrap(), &x!(100)); state.add_balance(t.sender().as_ref().unwrap(), &(100.into()));
let vm_factory = Default::default(); let vm_factory = Default::default();
let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap(); let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap();
let expected_trace = Some(Trace { let expected_trace = Some(Trace {
depth: 0, depth: 0,
action: trace::Action::Call(trace::Call { action: trace::Action::Call(trace::Call {
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"), from: "9cce34f7ab185c7aba1b7c8140d620b4bda941d6".into(),
to: x!(0xa), to: 0xa.into(),
value: x!(100), value: 100.into(),
gas: x!(79000), gas: 79000.into(),
input: vec![], input: vec![],
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
@ -864,10 +864,10 @@ fn should_trace_call_with_basic_subcall_transaction() {
subs: vec![Trace { subs: vec![Trace {
depth: 1, depth: 1,
action: trace::Action::Call(trace::Call { action: trace::Action::Call(trace::Call {
from: x!(0xa), from: 0xa.into(),
to: x!(0xb), to: 0xb.into(),
value: x!(69), value: 69.into(),
gas: x!(2300), gas: 2300.into(),
input: vec![], input: vec![],
}), }),
result: trace::Res::Call(trace::CallResult::default()), result: trace::Res::Call(trace::CallResult::default()),
@ -886,29 +886,29 @@ fn should_not_trace_call_with_invalid_basic_subcall_transaction() {
let mut state = get_temp_state_in(temp.as_path()); let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = x!(1_000_000); info.gas_limit = 1_000_000.into();
let engine = TestEngine::new(5); let engine = TestEngine::new(5);
let t = Transaction { let t = Transaction {
nonce: x!(0), nonce: 0.into(),
gas_price: x!(0), gas_price: 0.into(),
gas: x!(100_000), gas: 100_000.into(),
action: Action::Call(x!(0xa)), action: Action::Call(0xa.into()),
value: x!(100), value: 100.into(),
data: vec![], data: vec![],
}.sign(&"".sha3()); }.sign(&"".sha3());
state.init_code(&x!(0xa), FromHex::from_hex("600060006000600060ff600b6000f1").unwrap()); // not enough funds. state.init_code(&0xa.into(), FromHex::from_hex("600060006000600060ff600b6000f1").unwrap()); // not enough funds.
state.add_balance(t.sender().as_ref().unwrap(), &x!(100)); state.add_balance(t.sender().as_ref().unwrap(), &(100.into()));
let vm_factory = Default::default(); let vm_factory = Default::default();
let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap(); let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap();
let expected_trace = Some(Trace { let expected_trace = Some(Trace {
depth: 0, depth: 0,
action: trace::Action::Call(trace::Call { action: trace::Action::Call(trace::Call {
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"), from: "9cce34f7ab185c7aba1b7c8140d620b4bda941d6".into(),
to: x!(0xa), to: 0xa.into(),
value: x!(100), value: 100.into(),
gas: x!(79000), gas: 79000.into(),
input: vec![], input: vec![],
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
@ -929,30 +929,30 @@ fn should_trace_failed_subcall_transaction() {
let mut state = get_temp_state_in(temp.as_path()); let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = x!(1_000_000); info.gas_limit = 1_000_000.into();
let engine = TestEngine::new(5); let engine = TestEngine::new(5);
let t = Transaction { let t = Transaction {
nonce: x!(0), nonce: 0.into(),
gas_price: x!(0), gas_price: 0.into(),
gas: x!(100_000), gas: 100_000.into(),
action: Action::Call(x!(0xa)), action: Action::Call(0xa.into()),
value: x!(100), value: 100.into(),
data: vec![],//600480600b6000396000f35b600056 data: vec![],//600480600b6000396000f35b600056
}.sign(&"".sha3()); }.sign(&"".sha3());
state.init_code(&x!(0xa), FromHex::from_hex("60006000600060006000600b602b5a03f1").unwrap()); state.init_code(&0xa.into(), FromHex::from_hex("60006000600060006000600b602b5a03f1").unwrap());
state.init_code(&x!(0xb), FromHex::from_hex("5b600056").unwrap()); state.init_code(&0xb.into(), FromHex::from_hex("5b600056").unwrap());
state.add_balance(t.sender().as_ref().unwrap(), &x!(100)); state.add_balance(t.sender().as_ref().unwrap(), &(100.into()));
let vm_factory = Default::default(); let vm_factory = Default::default();
let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap(); let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap();
let expected_trace = Some(Trace { let expected_trace = Some(Trace {
depth: 0, depth: 0,
action: trace::Action::Call(trace::Call { action: trace::Action::Call(trace::Call {
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"), from: "9cce34f7ab185c7aba1b7c8140d620b4bda941d6".into(),
to: x!(0xa), to: 0xa.into(),
value: x!(100), value: 100.into(),
gas: x!(79000), gas: 79000.into(),
input: vec![], input: vec![],
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
@ -962,10 +962,10 @@ fn should_trace_failed_subcall_transaction() {
subs: vec![Trace { subs: vec![Trace {
depth: 1, depth: 1,
action: trace::Action::Call(trace::Call { action: trace::Action::Call(trace::Call {
from: x!(0xa), from: 0xa.into(),
to: x!(0xb), to: 0xb.into(),
value: x!(0), value: 0.into(),
gas: x!(78934), gas: 78934.into(),
input: vec![], input: vec![],
}), }),
result: trace::Res::FailedCall, result: trace::Res::FailedCall,
@ -984,31 +984,31 @@ fn should_trace_call_with_subcall_with_subcall_transaction() {
let mut state = get_temp_state_in(temp.as_path()); let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = x!(1_000_000); info.gas_limit = 1_000_000.into();
let engine = TestEngine::new(5); let engine = TestEngine::new(5);
let t = Transaction { let t = Transaction {
nonce: x!(0), nonce: 0.into(),
gas_price: x!(0), gas_price: 0.into(),
gas: x!(100_000), gas: 100_000.into(),
action: Action::Call(x!(0xa)), action: Action::Call(0xa.into()),
value: x!(100), value: 100.into(),
data: vec![], data: vec![],
}.sign(&"".sha3()); }.sign(&"".sha3());
state.init_code(&x!(0xa), FromHex::from_hex("60006000600060006000600b602b5a03f1").unwrap()); state.init_code(&0xa.into(), FromHex::from_hex("60006000600060006000600b602b5a03f1").unwrap());
state.init_code(&x!(0xb), FromHex::from_hex("60006000600060006000600c602b5a03f1").unwrap()); state.init_code(&0xb.into(), FromHex::from_hex("60006000600060006000600c602b5a03f1").unwrap());
state.init_code(&x!(0xc), FromHex::from_hex("6000").unwrap()); state.init_code(&0xc.into(), FromHex::from_hex("6000").unwrap());
state.add_balance(t.sender().as_ref().unwrap(), &x!(100)); state.add_balance(t.sender().as_ref().unwrap(), &(100.into()));
let vm_factory = Default::default(); let vm_factory = Default::default();
let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap(); let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap();
let expected_trace = Some(Trace { let expected_trace = Some(Trace {
depth: 0, depth: 0,
action: trace::Action::Call(trace::Call { action: trace::Action::Call(trace::Call {
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"), from: "9cce34f7ab185c7aba1b7c8140d620b4bda941d6".into(),
to: x!(0xa), to: 0xa.into(),
value: x!(100), value: 100.into(),
gas: x!(79000), gas: 79000.into(),
input: vec![], input: vec![],
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
@ -1018,10 +1018,10 @@ fn should_trace_call_with_subcall_with_subcall_transaction() {
subs: vec![Trace { subs: vec![Trace {
depth: 1, depth: 1,
action: trace::Action::Call(trace::Call { action: trace::Action::Call(trace::Call {
from: x!(0xa), from: 0xa.into(),
to: x!(0xb), to: 0xb.into(),
value: x!(0), value: 0.into(),
gas: x!(78934), gas: 78934.into(),
input: vec![], input: vec![],
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
@ -1031,10 +1031,10 @@ fn should_trace_call_with_subcall_with_subcall_transaction() {
subs: vec![Trace { subs: vec![Trace {
depth: 2, depth: 2,
action: trace::Action::Call(trace::Call { action: trace::Action::Call(trace::Call {
from: x!(0xb), from: 0xb.into(),
to: x!(0xc), to: 0xc.into(),
value: x!(0), value: 0.into(),
gas: x!(78868), gas: 78868.into(),
input: vec![], input: vec![],
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
@ -1057,31 +1057,31 @@ fn should_trace_failed_subcall_with_subcall_transaction() {
let mut state = get_temp_state_in(temp.as_path()); let mut state = get_temp_state_in(temp.as_path());
let mut info = EnvInfo::default(); let mut info = EnvInfo::default();
info.gas_limit = x!(1_000_000); info.gas_limit = 1_000_000.into();
let engine = TestEngine::new(5); let engine = TestEngine::new(5);
let t = Transaction { let t = Transaction {
nonce: x!(0), nonce: 0.into(),
gas_price: x!(0), gas_price: 0.into(),
gas: x!(100_000), gas: 100_000.into(),
action: Action::Call(x!(0xa)), action: Action::Call(0xa.into()),
value: x!(100), value: 100.into(),
data: vec![],//600480600b6000396000f35b600056 data: vec![],//600480600b6000396000f35b600056
}.sign(&"".sha3()); }.sign(&"".sha3());
state.init_code(&x!(0xa), FromHex::from_hex("60006000600060006000600b602b5a03f1").unwrap()); state.init_code(&0xa.into(), FromHex::from_hex("60006000600060006000600b602b5a03f1").unwrap());
state.init_code(&x!(0xb), FromHex::from_hex("60006000600060006000600c602b5a03f1505b601256").unwrap()); state.init_code(&0xb.into(), FromHex::from_hex("60006000600060006000600c602b5a03f1505b601256").unwrap());
state.init_code(&x!(0xc), FromHex::from_hex("6000").unwrap()); state.init_code(&0xc.into(), FromHex::from_hex("6000").unwrap());
state.add_balance(t.sender().as_ref().unwrap(), &x!(100)); state.add_balance(t.sender().as_ref().unwrap(), &(100.into()));
let vm_factory = Default::default(); let vm_factory = Default::default();
let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap(); let result = state.apply(&info, &engine, &vm_factory, &t, true).unwrap();
let expected_trace = Some(Trace { let expected_trace = Some(Trace {
depth: 0, depth: 0,
action: trace::Action::Call(trace::Call { action: trace::Action::Call(trace::Call {
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"), from: "9cce34f7ab185c7aba1b7c8140d620b4bda941d6".into(),
to: x!(0xa), to: 0xa.into(),
value: x!(100), value: 100.into(),
gas: x!(79000), gas: 79000.into(),
input: vec![], input: vec![],
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
@ -1091,21 +1091,21 @@ fn should_trace_failed_subcall_with_subcall_transaction() {
subs: vec![Trace { subs: vec![Trace {
depth: 1, depth: 1,
action: trace::Action::Call(trace::Call { action: trace::Action::Call(trace::Call {
from: x!(0xa), from: 0xa.into(),
to: x!(0xb), to: 0xb.into(),
value: x!(0), value: 0.into(),
gas: x!(78934), gas: 78934.into(),
input: vec![], input: vec![],
}), }),
result: trace::Res::FailedCall, result: trace::Res::FailedCall,
subs: vec![Trace { subs: vec![Trace {
depth: 2, depth: 2,
action: trace::Action::Call(trace::Call { action: trace::Action::Call(trace::Call {
from: x!(0xb), from: 0xb.into(),
to: x!(0xc), to: 0xc.into(),
value: x!(0), value: 0.into(),
gas: x!(78868), gas: 78868.into(),
input: vec![], input: vec![],
}), }),
result: trace::Res::Call(trace::CallResult { result: trace::Res::Call(trace::CallResult {
gas_used: U256::from(3), gas_used: U256::from(3),
@ -1125,7 +1125,7 @@ fn code_from_database() {
let temp = RandomTempPath::new(); let temp = RandomTempPath::new();
let (root, db) = { let (root, db) = {
let mut state = get_temp_state_in(temp.as_path()); let mut state = get_temp_state_in(temp.as_path());
state.require_or_from(&a, false, ||Account::new_contract(x!(42), x!(0)), |_|{}); state.require_or_from(&a, false, ||Account::new_contract(42.into(), 0.into()), |_|{});
state.init_code(&a, vec![1, 2, 3]); state.init_code(&a, vec![1, 2, 3]);
assert_eq!(state.code(&a), Some([1u8, 2, 3].to_vec())); assert_eq!(state.code(&a), Some([1u8, 2, 3].to_vec()));
state.commit(); state.commit();

View File

@ -59,19 +59,19 @@ mod test {
#[test] #[test]
fn create_delete() { fn create_delete() {
let a = PodState::from(map![ x!(1) => PodAccount::new(x!(69), x!(0), vec![], map![]) ]); let a = PodState::from(map![ 1.into() => PodAccount::new(69.into(), 0.into(), vec![], map![]) ]);
assert_eq!(StateDiff::diff_pod(&a, &PodState::new()), StateDiff(map![ assert_eq!(StateDiff::diff_pod(&a, &PodState::new()), StateDiff(map![
x!(1) => AccountDiff{ 1.into() => AccountDiff{
balance: Diff::Died(x!(69)), balance: Diff::Died(69.into()),
nonce: Diff::Died(x!(0)), nonce: Diff::Died(0.into()),
code: Diff::Died(vec![]), code: Diff::Died(vec![]),
storage: map![], storage: map![],
} }
])); ]));
assert_eq!(StateDiff::diff_pod(&PodState::new(), &a), StateDiff(map![ assert_eq!(StateDiff::diff_pod(&PodState::new(), &a), StateDiff(map![
x!(1) => AccountDiff{ 1.into() => AccountDiff{
balance: Diff::Born(x!(69)), balance: Diff::Born(69.into()),
nonce: Diff::Born(x!(0)), nonce: Diff::Born(0.into()),
code: Diff::Born(vec![]), code: Diff::Born(vec![]),
storage: map![], storage: map![],
} }
@ -80,23 +80,23 @@ mod test {
#[test] #[test]
fn create_delete_with_unchanged() { fn create_delete_with_unchanged() {
let a = PodState::from(map![ x!(1) => PodAccount::new(x!(69), x!(0), vec![], map![]) ]); let a = PodState::from(map![ 1.into() => PodAccount::new(69.into(), 0.into(), vec![], map![]) ]);
let b = PodState::from(map![ let b = PodState::from(map![
x!(1) => PodAccount::new(x!(69), x!(0), vec![], map![]), 1.into() => PodAccount::new(69.into(), 0.into(), vec![], map![]),
x!(2) => PodAccount::new(x!(69), x!(0), vec![], map![]) 2.into() => PodAccount::new(69.into(), 0.into(), vec![], map![])
]); ]);
assert_eq!(StateDiff::diff_pod(&a, &b), StateDiff(map![ assert_eq!(StateDiff::diff_pod(&a, &b), StateDiff(map![
x!(2) => AccountDiff{ 2.into() => AccountDiff{
balance: Diff::Born(x!(69)), balance: Diff::Born(69.into()),
nonce: Diff::Born(x!(0)), nonce: Diff::Born(0.into()),
code: Diff::Born(vec![]), code: Diff::Born(vec![]),
storage: map![], storage: map![],
} }
])); ]));
assert_eq!(StateDiff::diff_pod(&b, &a), StateDiff(map![ assert_eq!(StateDiff::diff_pod(&b, &a), StateDiff(map![
x!(2) => AccountDiff{ 2.into() => AccountDiff{
balance: Diff::Died(x!(69)), balance: Diff::Died(69.into()),
nonce: Diff::Died(x!(0)), nonce: Diff::Died(0.into()),
code: Diff::Died(vec![]), code: Diff::Died(vec![]),
storage: map![], storage: map![],
} }
@ -106,17 +106,17 @@ mod test {
#[test] #[test]
fn change_with_unchanged() { fn change_with_unchanged() {
let a = PodState::from(map![ let a = PodState::from(map![
x!(1) => PodAccount::new(x!(69), x!(0), vec![], map![]), 1.into() => PodAccount::new(69.into(), 0.into(), vec![], map![]),
x!(2) => PodAccount::new(x!(69), x!(0), vec![], map![]) 2.into() => PodAccount::new(69.into(), 0.into(), vec![], map![])
]); ]);
let b = PodState::from(map![ let b = PodState::from(map![
x!(1) => PodAccount::new(x!(69), x!(1), vec![], map![]), 1.into() => PodAccount::new(69.into(), 1.into(), vec![], map![]),
x!(2) => PodAccount::new(x!(69), x!(0), vec![], map![]) 2.into() => PodAccount::new(69.into(), 0.into(), vec![], map![])
]); ]);
assert_eq!(StateDiff::diff_pod(&a, &b), StateDiff(map![ assert_eq!(StateDiff::diff_pod(&a, &b), StateDiff(map![
x!(1) => AccountDiff{ 1.into() => AccountDiff{
balance: Diff::Same, balance: Diff::Same,
nonce: Diff::Changed(x!(0), x!(1)), nonce: Diff::Changed(0.into(), 1.into()),
code: Diff::Same, code: Diff::Same,
storage: map![], storage: map![],
} }

View File

@ -74,7 +74,7 @@ mod tests {
topics: vec![], topics: vec![],
data: vec![] data: vec![]
}); });
sub_state.sstore_clears_count = x!(5); sub_state.sstore_clears_count = 5.into();
sub_state.suicides.insert(address_from_u64(10u64)); sub_state.suicides.insert(address_from_u64(10u64));
let mut sub_state_2 = Substate::new(); let mut sub_state_2 = Substate::new();
@ -84,11 +84,11 @@ mod tests {
topics: vec![], topics: vec![],
data: vec![] data: vec![]
}); });
sub_state_2.sstore_clears_count = x!(7); sub_state_2.sstore_clears_count = 7.into();
sub_state.accrue(sub_state_2); sub_state.accrue(sub_state_2);
assert_eq!(sub_state.contracts_created.len(), 2); assert_eq!(sub_state.contracts_created.len(), 2);
assert_eq!(sub_state.sstore_clears_count, x!(12)); assert_eq!(sub_state.sstore_clears_count, 12.into());
assert_eq!(sub_state.suicides.len(), 1); assert_eq!(sub_state.suicides.len(), 1);
} }
} }

View File

@ -137,7 +137,7 @@ fn can_mine() {
let client_result = get_test_client_with_blocks(vec![dummy_blocks[0].clone()]); let client_result = get_test_client_with_blocks(vec![dummy_blocks[0].clone()]);
let client = client_result.reference(); let client = client_result.reference();
let b = client.prepare_sealing(Address::default(), x!(31415926), vec![], vec![]).0.unwrap(); let b = client.prepare_sealing(Address::default(), 31415926.into(), vec![], vec![]).0.unwrap();
assert_eq!(*b.block().header().parent_hash(), BlockView::new(&dummy_blocks[0]).header_view().sha3()); assert_eq!(*b.block().header().parent_hash(), BlockView::new(&dummy_blocks[0]).header_view().sha3());
assert!(client.try_seal(b.lock(), vec![]).is_ok()); assert!(client.try_seal(b.lock(), vec![]).is_ok());

View File

@ -99,8 +99,8 @@ pub fn create_test_block(header: &Header) -> Bytes {
fn create_unverifiable_block_header(order: u32, parent_hash: H256) -> Header { fn create_unverifiable_block_header(order: u32, parent_hash: H256) -> Header {
let mut header = Header::new(); let mut header = Header::new();
header.gas_limit = x!(0); header.gas_limit = 0.into();
header.difficulty = x!(order * 100); header.difficulty = (order * 100).into();
header.timestamp = (order * 10) as u64; header.timestamp = (order * 10) as u64;
header.number = order as u64; header.number = order as u64;
header.parent_hash = parent_hash; header.parent_hash = parent_hash;
@ -336,7 +336,7 @@ pub fn get_bad_state_dummy_block() -> Bytes {
block_header.timestamp = 40; block_header.timestamp = 40;
block_header.number = 1; block_header.number = 1;
block_header.parent_hash = test_spec.genesis_header().hash(); block_header.parent_hash = test_spec.genesis_header().hash();
block_header.state_root = x!(0xbad); block_header.state_root = 0xbad.into();
create_test_block(&block_header) create_test_block(&block_header)
} }

View File

@ -105,10 +105,10 @@ pub struct LocalizedReceipt {
fn test_basic() { fn test_basic() {
let expected = ::rustc_serialize::hex::FromHex::from_hex("f90162a02f697d671e9ae4ee24a43c4b0d7e15f1cb4ba6de1561120d43b9a4e8c4a8a6ee83040caeb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000f838f794dcf421d093428b096ca501a7cd1a740855a7976fc0a00000000000000000000000000000000000000000000000000000000000000000").unwrap(); let expected = ::rustc_serialize::hex::FromHex::from_hex("f90162a02f697d671e9ae4ee24a43c4b0d7e15f1cb4ba6de1561120d43b9a4e8c4a8a6ee83040caeb9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000f838f794dcf421d093428b096ca501a7cd1a740855a7976fc0a00000000000000000000000000000000000000000000000000000000000000000").unwrap();
let r = Receipt::new( let r = Receipt::new(
x!("2f697d671e9ae4ee24a43c4b0d7e15f1cb4ba6de1561120d43b9a4e8c4a8a6ee"), "2f697d671e9ae4ee24a43c4b0d7e15f1cb4ba6de1561120d43b9a4e8c4a8a6ee".into(),
x!(0x40cae), 0x40cae.into(),
vec![LogEntry { vec![LogEntry {
address: x!("dcf421d093428b096ca501a7cd1a740855a7976f"), address: "dcf421d093428b096ca501a7cd1a740855a7976f".into(),
topics: vec![], topics: vec![],
data: vec![0u8; 32] data: vec![0u8; 32]
}] }]

View File

@ -1294,8 +1294,8 @@ mod tests {
fn get_dummy_block(order: u32, parent_hash: H256) -> Bytes { fn get_dummy_block(order: u32, parent_hash: H256) -> Bytes {
let mut header = Header::new(); let mut header = Header::new();
header.gas_limit = x!(0); header.gas_limit = 0.into();
header.difficulty = x!(order * 100); header.difficulty = (order * 100).into();
header.timestamp = (order * 10) as u64; header.timestamp = (order * 10) as u64;
header.number = order as u64; header.number = order as u64;
header.parent_hash = parent_hash; header.parent_hash = parent_hash;
@ -1311,7 +1311,7 @@ mod tests {
fn get_dummy_blocks(order: u32, parent_hash: H256) -> Bytes { fn get_dummy_blocks(order: u32, parent_hash: H256) -> Bytes {
let mut rlp = RlpStream::new_list(1); let mut rlp = RlpStream::new_list(1);
rlp.append_raw(&get_dummy_block(order, parent_hash), 1); rlp.append_raw(&get_dummy_block(order, parent_hash), 1);
let difficulty: U256 = x!(100 * order); let difficulty: U256 = (100 * order).into();
rlp.append(&difficulty); rlp.append(&difficulty);
rlp.out() rlp.out()
} }

View File

@ -26,44 +26,50 @@ pub use sha3::*;
#[macro_export] #[macro_export]
macro_rules! hash_map { macro_rules! hash_map {
( $( $x:expr => $y:expr ),* ) => { () => { HashMap::new() };
vec![ $( ($x, $y) ),* ].into_iter().collect::<HashMap<_, _>>() ( $( $x:expr => $y:expr ),* ) => {{
} let mut x = HashMap::new();
$(
x.insert($x, $y);
)*
x
}}
} }
#[macro_export] #[macro_export]
macro_rules! hash_mapx { macro_rules! hash_map_into {
( $( $x:expr => $y:expr ),* ) => { () => { HashMap::new() };
vec![ $( ( From::from($x), From::from($y) ) ),* ].into_iter().collect::<HashMap<_, _>>() ( $( $x:expr => $y:expr ),* ) => {{
} let mut x = HashMap::new();
$(
x.insert($x.into(), $y.into());
)*
x
}}
} }
#[macro_export] #[macro_export]
macro_rules! map { macro_rules! map {
( $( $x:expr => $y:expr ),* ) => { () => { BTreeMap::new() };
vec![ $( ($x, $y) ),* ].into_iter().collect::<BTreeMap<_, _>>() ( $( $x:expr => $y:expr ),* ) => {{
} let mut x = BTreeMap::new();
$(
x.insert($x, $y);
)*
x
}}
} }
#[macro_export] #[macro_export]
macro_rules! mapx { macro_rules! map_into {
( $( $x:expr => $y:expr ),* ) => { () => { BTreeMap::new() };
vec![ $( ( From::from($x), From::from($y) ) ),* ].into_iter().collect::<BTreeMap<_, _>>() ( $( $x:expr => $y:expr ),* ) => {{
} let mut x = BTreeMap::new();
} $(
x.insert($x.into(), $y.into());
#[macro_export] )*
macro_rules! x { x
( $x:expr ) => { }}
From::from($x)
}
}
#[macro_export]
macro_rules! xx {
( $x:expr ) => {
From::from(From::from($x))
}
} }
#[macro_export] #[macro_export]

View File

@ -718,7 +718,7 @@ mod tests {
#[test] #[test]
fn from_and_to_u256() { fn from_and_to_u256() {
let u: U256 = x!(0x123456789abcdef0u64); let u: U256 = 0x123456789abcdef0u64.into();
let h = H256::from(u); let h = H256::from(u);
assert_eq!(H256::from(u), H256::from("000000000000000000000000000000000000000000000000123456789abcdef0")); assert_eq!(H256::from(u), H256::from("000000000000000000000000000000000000000000000000123456789abcdef0"));
let h_ref = H256::from(&u); let h_ref = H256::from(&u);

View File

@ -48,7 +48,7 @@ impl FromJson for Bytes {
impl FromJson for BTreeMap<H256, H256> { impl FromJson for BTreeMap<H256, H256> {
fn from_json(json: &Json) -> Self { fn from_json(json: &Json) -> Self {
match *json { match *json {
Json::Object(ref o) => o.iter().map(|(key, value)| (x!(&u256_from_str(key)), x!(&U256::from_json(value)))).collect(), Json::Object(ref o) => o.iter().map(|(key, value)| (u256_from_str(key).into(), U256::from_json(value).into())).collect(),
_ => BTreeMap::new(), _ => BTreeMap::new(),
} }
} }

View File

@ -554,7 +554,7 @@ mod tests {
H256::from_str("517ead924a9d0dc3124507e3393d175ce3ff7c1e96529c6c555ce9e51205e9b2").unwrap(), H256::from_str("517ead924a9d0dc3124507e3393d175ce3ff7c1e96529c6c555ce9e51205e9b2").unwrap(),
262144, 262144,
32)); 32));
key_file.account = Some(x!(i as u64)); key_file.account = Some((i as u64).into());
result.push(key_file.id.clone()); result.push(key_file.id.clone());
write_sstore.import_key(key_file).unwrap(); write_sstore.import_key(key_file).unwrap();
} }
@ -627,7 +627,7 @@ mod tests {
sstore.sign(&address, &H256::random()).unwrap() sstore.sign(&address, &H256::random()).unwrap()
}; };
assert!(signature != x!(0)); assert!(signature != 0.into());
} }
#[test] #[test]