diff --git a/.travis.yml b/.travis.yml
index 253b69d03..0f0766ee4 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -33,7 +33,7 @@ env:
global:
# GH_TOKEN
- secure: bumJASbZSU8bxJ0EyPUJmu16AiV9EXOpyOj86Jlq/Ty9CfwGqsSXt96uDyE+OUJf34RUFQMsw0nk37/zC4lcn6kqk2wpuH3N/o85Zo/cVZY/NusBWLQqtT5VbYWsV+u2Ua4Tmmsw8yVYQhYwU2ZOejNpflL+Cs9XGgORp1L+/gMRMC2y5Se6ZhwnKPQlRJ8LGsG1dzjQULxzADIt3/zuspNBS8a2urJwlHfGMkvHDoUWCviP/GXoSqw3TZR7FmKyxE19I8n9+iSvm9+oZZquvcgfUxMHn8Gq/b44UbPvjtFOg2yam4xdWXF/RyWCHdc/R9EHorSABeCbefIsm+zcUF3/YQxwpSxM4IZEeH2rTiC7dcrsKw3XsO16xFQz5YI5Bay+CT/wTdMmJd7DdYz7Dyf+pOvcM9WOf/zorxYWSBOMYy0uzbusU2iyIghQ82s7E/Ahg+WARtPgkuTLSB5aL1oCTBKHqQscMr7lo5Ti6RpWLxEdTQMBznc+bMr+6dEtkEcG9zqc6cE9XX+ox3wTU6+HVMfQ1ltCntJ4UKcw3A6INEbw9wgocQa812CIASQ2fE+SCAbz6JxBjIAlFUnD1lUB7S8PdMPwn9plfQgKQ2A5YZqg6FnBdf0rQXIJYxQWKHXj/rBHSUCT0tHACDlzTA+EwWggvkP5AGIxRxm8jhw=
- - TARGETS="-p ethash -p ethcore-util -p ethcore -p ethsync -p ethcore-rpc -p parity -p ethminer -p ethjson -p ethcore-dapps"
+ - TARGETS="-p ethash -p ethcore-util -p ethcore -p ethsync -p ethcore-rpc -p parity -p ethminer -p ethjson -p ethcore-dapps -p ethcore-signer"
- ARCHIVE_SUFFIX="-${TRAVIS_OS_NAME}-${TRAVIS_TAG}"
- KCOV_FEATURES=""
- KCOV_CMD="./kcov-master/tmp/usr/local/bin/kcov --exclude-pattern /usr/,/.cargo,/root/.multirust,src/tests,util/json-tests,util/src/network/tests,sync/src/tests,ethcore/src/tests,ethcore/src/evm/tests target/kcov"
@@ -71,6 +71,7 @@ after_success: |
$KCOV_CMD target/debug/deps/ethsync-* &&
$KCOV_CMD target/debug/deps/ethcore_rpc-* &&
$KCOV_CMD target/debug/deps/ethcore_dapps-* &&
+ $KCOV_CMD target/debug/deps/ethcore_signer-* &&
$KCOV_CMD target/debug/deps/ethminer-* &&
$KCOV_CMD target/debug/deps/ethjson-* &&
$KCOV_CMD target/debug/parity-* &&
diff --git a/Cargo.lock b/Cargo.lock
index bb44cdab6..4dbcd1825 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -15,6 +15,7 @@ dependencies = [
"ethcore-ipc-codegen 1.2.0",
"ethcore-ipc-nano 1.2.0",
"ethcore-rpc 1.2.0",
+ "ethcore-signer 1.2.0",
"ethcore-util 1.2.0",
"ethminer 1.2.0",
"ethsync 1.2.0",
@@ -340,6 +341,17 @@ dependencies = [
"transient-hashmap 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "ethcore-signer"
+version = "1.2.0"
+dependencies = [
+ "clippy 0.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ethcore-util 1.2.0",
+ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "ethcore-util"
version = "1.2.0"
@@ -902,7 +914,7 @@ dependencies = [
[[package]]
name = "parity-dapps-wallet"
version = "0.5.0"
-source = "git+https://github.com/ethcore/parity-dapps-wallet-rs.git#37b1691d74ad9bdabc64f58684d9d0a6d1aeef66"
+source = "git+https://github.com/ethcore/parity-dapps-wallet-rs.git#25402ce0a02ae49eb66c9e3852b392267a027ea3"
dependencies = [
"parity-dapps 0.3.0 (git+https://github.com/ethcore/parity-dapps-rs.git)",
]
diff --git a/Cargo.toml b/Cargo.toml
index eb1b87dfe..d7813468a 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -30,6 +30,7 @@ ethsync = { path = "sync" }
ethminer = { path = "miner" }
ethcore-devtools = { path = "devtools" }
ethcore-rpc = { path = "rpc", optional = true }
+ethcore-signer = { path = "signer", optional = true }
ethcore-dapps = { path = "dapps", optional = true }
semver = "0.2"
ethcore-ipc-nano = { path = "ipc/nano" }
@@ -42,11 +43,11 @@ version = "0.8"
default-features = false
[features]
-default = ["rpc", "dapps"]
+default = ["rpc", "dapps", "ethcore-signer"]
rpc = ["ethcore-rpc"]
dapps = ["ethcore-dapps"]
dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev", "ethcore-rpc/dev", "ethminer/dev",
-"ethcore-dapps/dev"]
+"ethcore-dapps/dev", "ethcore-signer/dev"]
travis-beta = ["ethcore/json-tests"]
travis-nightly = ["ethcore/json-tests", "dev"]
diff --git a/cov.sh b/cov.sh
index 7145dfab4..084e95284 100755
--- a/cov.sh
+++ b/cov.sh
@@ -23,6 +23,7 @@ cargo test \
-p ethcore-rpc \
-p parity \
-p ethminer \
+ -p ethcore-signer \
-p ethcore-dapps \
--no-run || exit $?
rm -rf target/coverage
@@ -34,6 +35,7 @@ kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage t
kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethcore_util-*
kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethsync-*
kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethcore_rpc-*
+kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethcore_signer-*
kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethcore_dapps-*
kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethminer-*
xdg-open target/coverage/index.html
diff --git a/doc.sh b/doc.sh
index 68f2e2b4d..0b75f6c38 100755
--- a/doc.sh
+++ b/doc.sh
@@ -7,6 +7,7 @@ cargo doc --no-deps --verbose \
-p ethcore \
-p ethsync \
-p ethcore-rpc \
+ -p ethcore-signer \
-p ethcore-dapps \
-p parity \
-p ethminer
diff --git a/fmt.sh b/fmt.sh
index 81bd4fafc..624b404ff 100755
--- a/fmt.sh
+++ b/fmt.sh
@@ -9,6 +9,7 @@ $RUSTFMT ./json/src/lib.rs
$RUSTFMT ./miner/src/lib.rs
$RUSTFMT ./parity/main.rs
$RUSTFMT ./rpc/src/lib.rs
+$RUSTFMT ./signer/src/lib.rs
$RUSTFMT ./dapps/src/lib.rs
$RUSTFMT ./sync/src/lib.rs
$RUSTFMT ./util/src/lib.rs
diff --git a/hook.sh b/hook.sh
index 667daafe4..978f0ca23 100755
--- a/hook.sh
+++ b/hook.sh
@@ -7,6 +7,6 @@ echo "set -e" >> $FILE
echo "cargo build --features dev" >> $FILE
# Build tests
echo "cargo test --no-run --features dev \\" >> $FILE
-echo " -p ethash -p ethcore-util -p ethcore -p ethsync -p ethcore-rpc -p parity -p ethminer -p ethcore-dapps" >> $FILE
+echo " -p ethash -p ethcore-util -p ethcore -p ethsync -p ethcore-rpc -p parity -p ethminer -p ethcore-dapps -p ethcore-signer" >> $FILE
echo "" >> $FILE
chmod +x $FILE
diff --git a/parity/migration.rs b/parity/migration.rs
index 76bf494ab..d41c502cc 100644
--- a/parity/migration.rs
+++ b/parity/migration.rs
@@ -14,13 +14,13 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see .
-use std::{fs, env};
+use std::fs;
use std::fs::File;
use std::io::{Read, Write, Error as IoError, ErrorKind};
use std::path::PathBuf;
use std::fmt::{Display, Formatter, Error as FmtError};
use util::migration::{Manager as MigrationManager, Config as MigrationConfig, MigrationIterator};
-use util::kvdb::Database;
+use util::kvdb::{Database, DatabaseConfig};
use ethcore::migrations;
/// Database is assumed to be at default version, when no version file is found.
@@ -109,10 +109,19 @@ fn extras_database_path(path: &PathBuf) -> PathBuf {
}
/// Temporary database path used for migration.
-fn temp_database_path() -> PathBuf {
- let mut dir = env::temp_dir();
- dir.push("parity_migration");
- dir
+fn temp_database_path(path: &PathBuf) -> PathBuf {
+ let mut temp_path = path.clone();
+ temp_path.pop();
+ temp_path.push("temp_migration");
+ temp_path
+}
+
+/// Database backup
+fn backup_database_path(path: &PathBuf) -> PathBuf {
+ let mut backup_path = path.clone();
+ backup_path.pop();
+ backup_path.push("temp_backup");
+ backup_path
}
/// Default migration settings.
@@ -144,26 +153,40 @@ fn migrate_database(version: u32, path: PathBuf, migrations: MigrationManager) -
println!("Migrating database {} from version {} to {}", path.to_string_lossy(), version, CURRENT_VERSION);
- // get temp path
- let temp_path = temp_database_path();
+ let temp_path = temp_database_path(&path);
+ let backup_path = backup_database_path(&path);
// remote the dir if it exists
let _ = fs::remove_dir_all(&temp_path);
+ let _ = fs::remove_dir_all(&backup_path);
{
+ let db_config = DatabaseConfig {
+ prefix_size: None,
+ max_open_files: 64,
+ };
+
// open old database
- let old = try!(Database::open_default(path.to_str().unwrap()).map_err(|_| Error::MigrationFailed));
+ let old = try!(Database::open(&db_config, path.to_str().unwrap()).map_err(|_| Error::MigrationFailed));
// create new database
- let mut temp = try!(Database::open_default(temp_path.to_str().unwrap()).map_err(|_| Error::MigrationFailed));
+ let mut temp = try!(Database::open(&db_config, temp_path.to_str().unwrap()).map_err(|_| Error::MigrationFailed));
// migrate old database to the new one
try!(migrations.execute(MigrationIterator::from(old.iter()), version, &mut temp).map_err(|_| Error::MigrationFailed));
}
- // replace the old database with the new one
- try!(fs::remove_dir_all(&path));
- try!(fs::rename(&temp_path, &path));
+ // create backup
+ try!(fs::rename(&path, &backup_path));
+ // replace the old database with the new one
+ if let Err(err) = fs::rename(&temp_path, &path) {
+ // if something went wrong, bring back backup
+ try!(fs::rename(&backup_path, path));
+ return Err(From::from(err));
+ }
+
+ // remove backup
+ try!(fs::remove_dir_all(&backup_path));
println!("Migration finished");
Ok(())
diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs
index d52fc9f4c..e69de29bb 100644
--- a/rpc/src/v1/tests/eth.rs
+++ b/rpc/src/v1/tests/eth.rs
@@ -1,724 +0,0 @@
-// 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 .
-
-use std::str::FromStr;
-use std::collections::HashMap;
-use std::sync::{Arc, RwLock};
-use jsonrpc_core::IoHandler;
-use util::hash::{Address, H256, FixedHash};
-use util::numbers::{Uint, U256};
-use util::keys::{TestAccount, TestAccountProvider};
-use ethcore::client::{TestBlockChainClient, EachBlockWith, Executed, TransactionID};
-use ethcore::log_entry::{LocalizedLogEntry, LogEntry};
-use ethcore::receipt::LocalizedReceipt;
-use ethcore::transaction::{Transaction, Action};
-use ethminer::ExternalMiner;
-use v1::{Eth, EthClient};
-use v1::tests::helpers::{TestSyncProvider, Config, TestMinerService};
-
-fn blockchain_client() -> Arc {
- let client = TestBlockChainClient::new();
- Arc::new(client)
-}
-
-fn accounts_provider() -> Arc {
- let mut accounts = HashMap::new();
- accounts.insert(Address::from(1), TestAccount::new("test"));
- let ap = TestAccountProvider::new(accounts);
- Arc::new(ap)
-}
-
-fn sync_provider() -> Arc {
- Arc::new(TestSyncProvider::new(Config {
- network_id: U256::from(3),
- num_peers: 120,
- }))
-}
-
-fn miner_service() -> Arc {
- Arc::new(TestMinerService::default())
-}
-
-struct EthTester {
- pub client: Arc,
- pub sync: Arc,
- pub accounts_provider: Arc,
- miner: Arc,
- hashrates: Arc>>,
- pub io: IoHandler,
-}
-
-impl Default for EthTester {
- fn default() -> Self {
- let client = blockchain_client();
- let sync = sync_provider();
- let ap = accounts_provider();
- let miner = miner_service();
- let hashrates = Arc::new(RwLock::new(HashMap::new()));
- let external_miner = Arc::new(ExternalMiner::new(hashrates.clone()));
- let eth = EthClient::new(&client, &sync, &ap, &miner, &external_miner).to_delegate();
- let io = IoHandler::new();
- io.add_delegate(eth);
- EthTester {
- client: client,
- sync: sync,
- accounts_provider: ap,
- miner: miner,
- io: io,
- hashrates: hashrates,
- }
- }
-}
-
-#[test]
-fn rpc_eth_protocol_version() {
- let request = r#"{"jsonrpc": "2.0", "method": "eth_protocolVersion", "params": [], "id": 1}"#;
- let response = r#"{"jsonrpc":"2.0","result":"63","id":1}"#;
-
- assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
-}
-
-#[test]
-#[ignore]
-fn rpc_eth_syncing() {
- unimplemented!()
-}
-
-#[test]
-fn rpc_eth_hashrate() {
- let tester = EthTester::default();
- tester.hashrates.write().unwrap().insert(H256::from(0), U256::from(0xfffa));
- tester.hashrates.write().unwrap().insert(H256::from(0), U256::from(0xfffb));
- tester.hashrates.write().unwrap().insert(H256::from(1), U256::from(0x1));
-
- let request = r#"{"jsonrpc": "2.0", "method": "eth_hashrate", "params": [], "id": 1}"#;
- let response = r#"{"jsonrpc":"2.0","result":"0xfffc","id":1}"#;
-
- assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
-}
-
-#[test]
-fn rpc_eth_submit_hashrate() {
- let tester = EthTester::default();
-
- let request = r#"{
- "jsonrpc": "2.0",
- "method": "eth_submitHashrate",
- "params": [
- "0x0000000000000000000000000000000000000000000000000000000000500000",
- "0x59daa26581d0acd1fce254fb7e85952f4c09d0915afd33d3886cd914bc7d283c"],
- "id": 1
- }"#;
- let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
-
- assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
- assert_eq!(tester.hashrates.read().unwrap().get(&H256::from("0x59daa26581d0acd1fce254fb7e85952f4c09d0915afd33d3886cd914bc7d283c")).cloned(),
- Some(U256::from(0x500_000)));
-}
-
-#[test]
-#[ignore]
-fn rpc_eth_author() {
- unimplemented!()
-}
-
-#[test]
-fn rpc_eth_mining() {
- let tester = EthTester::default();
-
- let request = r#"{"jsonrpc": "2.0", "method": "eth_mining", "params": [], "id": 1}"#;
- let response = r#"{"jsonrpc":"2.0","result":false,"id":1}"#;
- assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
-
- tester.hashrates.write().unwrap().insert(H256::from(1), U256::from(0x1));
-
- let request = r#"{"jsonrpc": "2.0", "method": "eth_mining", "params": [], "id": 1}"#;
- let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
- assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
-}
-
-#[test]
-fn rpc_eth_gas_price() {
- let request = r#"{"jsonrpc": "2.0", "method": "eth_gasPrice", "params": [], "id": 1}"#;
- let response = r#"{"jsonrpc":"2.0","result":"0x04a817c800","id":1}"#;
-
- assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
-}
-
-#[test]
-fn rpc_eth_accounts() {
- let request = r#"{"jsonrpc": "2.0", "method": "eth_accounts", "params": [], "id": 1}"#;
- let response = r#"{"jsonrpc":"2.0","result":["0x0000000000000000000000000000000000000001"],"id":1}"#;
-
- assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
-}
-
-#[test]
-fn rpc_eth_block_number() {
- let tester = EthTester::default();
- tester.client.add_blocks(10, EachBlockWith::Nothing);
-
- let request = r#"{"jsonrpc": "2.0", "method": "eth_blockNumber", "params": [], "id": 1}"#;
- let response = r#"{"jsonrpc":"2.0","result":"0x0a","id":1}"#;
-
- assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
-}
-
-#[test]
-fn rpc_eth_balance() {
- let tester = EthTester::default();
- tester.client.set_balance(Address::from(1), U256::from(5));
-
- let request = r#"{
- "jsonrpc": "2.0",
- "method": "eth_getBalance",
- "params": ["0x0000000000000000000000000000000000000001", "latest"],
- "id": 1
- }"#;
- let response = r#"{"jsonrpc":"2.0","result":"0x05","id":1}"#;
-
- assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
-}
-
-#[ignore] //TODO: propert test
-#[test]
-fn rpc_eth_balance_pending() {
- let tester = EthTester::default();
-
- let request = r#"{
- "jsonrpc": "2.0",
- "method": "eth_getBalance",
- "params": ["0x0000000000000000000000000000000000000001", "latest"],
- "id": 1
- }"#;
- let response = r#"{"jsonrpc":"2.0","result":"0x","id":1}"#;
-
- assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
-}
-
-#[test]
-fn rpc_eth_storage_at() {
- let tester = EthTester::default();
- tester.client.set_storage(Address::from(1), H256::from(4), H256::from(7));
-
- let request = r#"{
- "jsonrpc": "2.0",
- "method": "eth_getStorageAt",
- "params": ["0x0000000000000000000000000000000000000001", "0x4", "latest"],
- "id": 1
- }"#;
- let response = r#"{"jsonrpc":"2.0","result":"0x07","id":1}"#;
-
- assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
-}
-
-#[test]
-fn rpc_eth_transaction_count() {
- let request = r#"{
- "jsonrpc": "2.0",
- "method": "eth_getTransactionCount",
- "params": ["0x0000000000000000000000000000000000000001", "latest"],
- "id": 1
- }"#;
- let response = r#"{"jsonrpc":"2.0","result":"0x00","id":1}"#;
-
- assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
-}
-
-#[test]
-fn rpc_eth_block_transaction_count_by_hash() {
- let request = r#"{
- "jsonrpc": "2.0",
- "method": "eth_getBlockTransactionCountByHash",
- "params": ["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"],
- "id": 1
- }"#;
- let response = r#"{"jsonrpc":"2.0","result":null,"id":1}"#;
-
- assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
-}
-
-#[test]
-fn rpc_eth_transaction_count_by_number() {
- let request = r#"{
- "jsonrpc": "2.0",
- "method": "eth_getBlockTransactionCountByNumber",
- "params": ["latest"],
- "id": 1
- }"#;
- let response = r#"{"jsonrpc":"2.0","result":"0x00","id":1}"#;
-
- assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
-}
-
-#[test]
-fn rpc_eth_transaction_count_by_number_pending() {
- let request = r#"{
- "jsonrpc": "2.0",
- "method": "eth_getBlockTransactionCountByNumber",
- "params": ["pending"],
- "id": 1
- }"#;
- let response = r#"{"jsonrpc":"2.0","result":"0x01","id":1}"#;
-
- assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
-}
-
-#[test]
-fn rpc_eth_pending_transaction_by_hash() {
- use util::*;
- use ethcore::transaction::*;
-
- let tester = EthTester::default();
- {
- let tx: SignedTransaction = decode(&FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap());
- tester.miner.pending_transactions.lock().unwrap().insert(H256::zero(), tx);
- }
-
- let response = r#"{"jsonrpc":"2.0","result":{"blockHash":null,"blockNumber":null,"from":"0x0f65fe9276bc9a24ae7083ae28e2660ef72df99e","gas":"0x5208","gasPrice":"0x01","hash":"0x41df922fd0d4766fcc02e161f8295ec28522f329ae487f14d811e4b64c8d6e31","input":"0x","nonce":"0x00","to":"0x095e7baea6a6c7c4c2dfeb977efac326af552d87","transactionIndex":null,"value":"0x0a"},"id":1}"#;
- let request = r#"{
- "jsonrpc": "2.0",
- "method": "eth_getTransactionByHash",
- "params": ["0x0000000000000000000000000000000000000000000000000000000000000000"],
- "id": 1
- }"#;
- assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
-}
-
-
-#[test]
-fn rpc_eth_uncle_count_by_block_hash() {
- let request = r#"{
- "jsonrpc": "2.0",
- "method": "eth_getUncleCountByBlockHash",
- "params": ["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"],
- "id": 1
- }"#;
- let response = r#"{"jsonrpc":"2.0","result":null,"id":1}"#;
-
- assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
-}
-
-#[test]
-fn rpc_eth_uncle_count_by_block_number() {
- let request = r#"{
- "jsonrpc": "2.0",
- "method": "eth_getUncleCountByBlockNumber",
- "params": ["latest"],
- "id": 1
- }"#;
- let response = r#"{"jsonrpc":"2.0","result":"0x00","id":1}"#;
-
- assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
-}
-
-#[test]
-fn rpc_eth_code() {
- let tester = EthTester::default();
- tester.client.set_code(Address::from(1), vec![0xff, 0x21]);
-
- let request = r#"{
- "jsonrpc": "2.0",
- "method": "eth_getCode",
- "params": ["0x0000000000000000000000000000000000000001", "latest"],
- "id": 1
- }"#;
- let response = r#"{"jsonrpc":"2.0","result":"0xff21","id":1}"#;
-
- assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
-}
-
-#[test]
-fn rpc_eth_call() {
- let tester = EthTester::default();
- tester.client.set_execution_result(Executed {
- gas: U256::zero(),
- gas_used: U256::from(0xff30),
- refunded: U256::from(0x5),
- cumulative_gas_used: U256::zero(),
- logs: vec![],
- contracts_created: vec![],
- output: vec![0x12, 0x34, 0xff],
- trace: None,
- });
-
- let request = r#"{
- "jsonrpc": "2.0",
- "method": "eth_call",
- "params": [{
- "from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155",
- "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
- "gas": "0x76c0",
- "gasPrice": "0x9184e72a000",
- "value": "0x9184e72a",
- "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
- },
- "latest"],
- "id": 1
- }"#;
- let response = r#"{"jsonrpc":"2.0","result":"0x1234ff","id":1}"#;
-
- assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
-}
-
-#[test]
-fn rpc_eth_call_default_block() {
- let tester = EthTester::default();
- tester.client.set_execution_result(Executed {
- gas: U256::zero(),
- gas_used: U256::from(0xff30),
- refunded: U256::from(0x5),
- cumulative_gas_used: U256::zero(),
- logs: vec![],
- contracts_created: vec![],
- output: vec![0x12, 0x34, 0xff],
- trace: None,
- });
-
- let request = r#"{
- "jsonrpc": "2.0",
- "method": "eth_call",
- "params": [{
- "from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155",
- "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
- "gas": "0x76c0",
- "gasPrice": "0x9184e72a000",
- "value": "0x9184e72a",
- "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
- }],
- "id": 1
- }"#;
- let response = r#"{"jsonrpc":"2.0","result":"0x1234ff","id":1}"#;
-
- assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
-}
-
-#[test]
-fn rpc_eth_estimate_gas() {
- let tester = EthTester::default();
- tester.client.set_execution_result(Executed {
- gas: U256::zero(),
- gas_used: U256::from(0xff30),
- refunded: U256::from(0x5),
- cumulative_gas_used: U256::zero(),
- logs: vec![],
- contracts_created: vec![],
- output: vec![0x12, 0x34, 0xff],
- trace: None,
- });
-
- let request = r#"{
- "jsonrpc": "2.0",
- "method": "eth_estimateGas",
- "params": [{
- "from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155",
- "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
- "gas": "0x76c0",
- "gasPrice": "0x9184e72a000",
- "value": "0x9184e72a",
- "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
- },
- "latest"],
- "id": 1
- }"#;
- let response = r#"{"jsonrpc":"2.0","result":"0xff35","id":1}"#;
-
- assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
-}
-
-#[test]
-fn rpc_eth_estimate_gas_default_block() {
- let tester = EthTester::default();
- tester.client.set_execution_result(Executed {
- gas: U256::zero(),
- gas_used: U256::from(0xff30),
- refunded: U256::from(0x5),
- cumulative_gas_used: U256::zero(),
- logs: vec![],
- contracts_created: vec![],
- output: vec![0x12, 0x34, 0xff],
- trace: None,
- });
-
- let request = r#"{
- "jsonrpc": "2.0",
- "method": "eth_estimateGas",
- "params": [{
- "from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155",
- "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
- "gas": "0x76c0",
- "gasPrice": "0x9184e72a000",
- "value": "0x9184e72a",
- "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
- }],
- "id": 1
- }"#;
- let response = r#"{"jsonrpc":"2.0","result":"0xff35","id":1}"#;
-
- assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
-}
-
-#[test]
-fn rpc_eth_send_transaction() {
- let account = TestAccount::new("123");
- let address = account.address();
- let secret = account.secret.clone();
-
- let tester = EthTester::default();
- tester.accounts_provider.accounts.write().unwrap().insert(address.clone(), account);
- let request = r#"{
- "jsonrpc": "2.0",
- "method": "eth_sendTransaction",
- "params": [{
- "from": ""#.to_owned() + format!("0x{:?}", address).as_ref() + r#"",
- "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
- "gas": "0x76c0",
- "gasPrice": "0x9184e72a000",
- "value": "0x9184e72a"
- }],
- "id": 1
- }"#;
-
- let t = Transaction {
- nonce: U256::zero(),
- gas_price: U256::from(0x9184e72a000u64),
- gas: U256::from(0x76c0),
- action: Action::Call(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()),
- value: U256::from(0x9184e72au64),
- data: vec![]
- }.sign(&secret);
-
- let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:?}", t.hash()).as_ref() + r#"","id":1}"#;
-
- assert_eq!(tester.io.handle_request(request.as_ref()), Some(response));
-
- tester.miner.last_nonces.write().unwrap().insert(address.clone(), U256::zero());
-
- let t = Transaction {
- nonce: U256::one(),
- gas_price: U256::from(0x9184e72a000u64),
- gas: U256::from(0x76c0),
- action: Action::Call(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()),
- value: U256::from(0x9184e72au64),
- data: vec![]
- }.sign(&secret);
-
- let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:?}", t.hash()).as_ref() + r#"","id":1}"#;
-
- assert_eq!(tester.io.handle_request(request.as_ref()), Some(response));
-}
-
-#[test]
-fn rpc_eth_sign_and_send_transaction_with_invalid_password() {
- let account = TestAccount::new("password123");
- let address = account.address();
-
- let tester = EthTester::default();
- tester.accounts_provider.accounts.write().unwrap().insert(address.clone(), account);
- let request = r#"{
- "jsonrpc": "2.0",
- "method": "eth_signAndSendTransaction",
- "params": [{
- "from": ""#.to_owned() + format!("0x{:?}", address).as_ref() + r#"",
- "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
- "gas": "0x76c0",
- "gasPrice": "0x9184e72a000",
- "value": "0x9184e72a"
- }, "password321"],
- "id": 1
- }"#;
-
- let response = r#"{"jsonrpc":"2.0","result":"0x0000000000000000000000000000000000000000000000000000000000000000","id":1}"#;
-
- assert_eq!(tester.io.handle_request(request.as_ref()), Some(response.into()));
-}
-
-#[test]
-fn rpc_eth_sign_and_send_transaction() {
- let account = TestAccount::new("password123");
- let address = account.address();
- let secret = account.secret.clone();
-
- let tester = EthTester::default();
- tester.accounts_provider.accounts.write().unwrap().insert(address.clone(), account);
- let request = r#"{
- "jsonrpc": "2.0",
- "method": "eth_signAndSendTransaction",
- "params": [{
- "from": ""#.to_owned() + format!("0x{:?}", address).as_ref() + r#"",
- "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
- "gas": "0x76c0",
- "gasPrice": "0x9184e72a000",
- "value": "0x9184e72a"
- }, "password123"],
- "id": 1
- }"#;
-
- let t = Transaction {
- nonce: U256::zero(),
- gas_price: U256::from(0x9184e72a000u64),
- gas: U256::from(0x76c0),
- action: Action::Call(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()),
- value: U256::from(0x9184e72au64),
- data: vec![]
- }.sign(&secret);
-
- let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:?}", t.hash()).as_ref() + r#"","id":1}"#;
-
- assert_eq!(tester.io.handle_request(request.as_ref()), Some(response));
-
- tester.miner.last_nonces.write().unwrap().insert(address.clone(), U256::zero());
-
- let t = Transaction {
- nonce: U256::one(),
- gas_price: U256::from(0x9184e72a000u64),
- gas: U256::from(0x76c0),
- action: Action::Call(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()),
- value: U256::from(0x9184e72au64),
- data: vec![]
- }.sign(&secret);
-
- let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:?}", t.hash()).as_ref() + r#"","id":1}"#;
-
- assert_eq!(tester.io.handle_request(request.as_ref()), Some(response));
-}
-
-#[test]
-#[ignore]
-fn rpc_eth_send_raw_transaction() {
- unimplemented!()
-}
-
-#[test]
-#[ignore]
-fn rpc_eth_sign() {
- unimplemented!()
-}
-
-#[test]
-fn rpc_eth_transaction_receipt() {
- let receipt = LocalizedReceipt {
- transaction_hash: H256::zero(),
- transaction_index: 0,
- block_hash: H256::from_str("ed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5").unwrap(),
- block_number: 0x4510c,
- cumulative_gas_used: U256::from(0x20),
- gas_used: U256::from(0x10),
- contract_address: None,
- logs: vec![LocalizedLogEntry {
- entry: LogEntry {
- address: Address::from_str("33990122638b9132ca29c723bdf037f1a891a70c").unwrap(),
- topics: vec![
- H256::from_str("a6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc").unwrap(),
- H256::from_str("4861736852656700000000000000000000000000000000000000000000000000").unwrap()
- ],
- data: vec![],
- },
- block_hash: H256::from_str("ed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5").unwrap(),
- block_number: 0x4510c,
- transaction_hash: H256::new(),
- transaction_index: 0,
- log_index: 1,
- }]
- };
-
- let hash = H256::from_str("b903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238").unwrap();
- let tester = EthTester::default();
- tester.client.set_transaction_receipt(TransactionID::Hash(hash), receipt);
-
- let request = r#"{
- "jsonrpc": "2.0",
- "method": "eth_getTransactionReceipt",
- "params": ["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"],
- "id": 1
- }"#;
- let response = r#"{"jsonrpc":"2.0","result":{"blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x04510c","contractAddress":null,"cumulativeGasUsed":"0x20","gasUsed":"0x10","logs":[{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x04510c","data":"0x","logIndex":"0x01","topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x00","type":"mined"}],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x00"},"id":1}"#;
-
- assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
-}
-
-#[test]
-fn rpc_eth_transaction_receipt_null() {
- let tester = EthTester::default();
-
- let request = r#"{
- "jsonrpc": "2.0",
- "method": "eth_getTransactionReceipt",
- "params": ["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"],
- "id": 1
- }"#;
- let response = r#"{"jsonrpc":"2.0","result":null,"id":1}"#;
-
- assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
-}
-
-#[test]
-fn rpc_eth_compilers() {
- let request = r#"{"jsonrpc": "2.0", "method": "eth_getCompilers", "params": [], "id": 1}"#;
- let response = r#"{"jsonrpc":"2.0","result":[],"id":1}"#;
-
- assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
-}
-
-#[test]
-fn rpc_eth_compile_lll() {
- let request = r#"{"jsonrpc": "2.0", "method": "eth_compileLLL", "params": [], "id": 1}"#;
- let response = r#"{"jsonrpc":"2.0","error":{"code":-32603,"message":"Internal error","data":null},"id":1}"#;
-
- assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
-}
-
-#[test]
-fn rpc_eth_compile_solidity() {
- let request = r#"{"jsonrpc": "2.0", "method": "eth_compileSolidity", "params": [], "id": 1}"#;
- let response = r#"{"jsonrpc":"2.0","error":{"code":-32603,"message":"Internal error","data":null},"id":1}"#;
-
- assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
-}
-
-#[test]
-fn rpc_eth_compile_serpent() {
- let request = r#"{"jsonrpc": "2.0", "method": "eth_compileSerpent", "params": [], "id": 1}"#;
- let response = r#"{"jsonrpc":"2.0","error":{"code":-32603,"message":"Internal error","data":null},"id":1}"#;
-
- assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
-}
-
-#[test]
-fn returns_no_work_if_cant_mine() {
- let eth_tester = EthTester::default();
- eth_tester.client.set_queue_size(10);
-
- let request = r#"{"jsonrpc": "2.0", "method": "eth_getWork", "params": [], "id": 1}"#;
- let response = r#"{"jsonrpc":"2.0","result":["","",""],"id":1}"#;
-
- assert_eq!(eth_tester.io.handle_request(request), Some(response.to_owned()));
-}
-
-#[ignore]
-// enable once TestMinerService supports the mining API.
-#[test]
-fn returns_error_if_can_mine_and_no_closed_block() {
- use ethsync::{SyncState};
-
- let eth_tester = EthTester::default();
- eth_tester.sync.status.write().unwrap().state = SyncState::Idle;
-
- let request = r#"{"jsonrpc": "2.0", "method": "eth_getWork", "params": [], "id": 1}"#;
- let response = r#"{"jsonrpc":"2.0","error":{"code":-32603,"message":"Internal error","data":null},"id":1}"#;
-
- assert_eq!(eth_tester.io.handle_request(request), Some(response.to_owned()));
-}
diff --git a/rpc/src/v1/tests/mocked/eth.rs b/rpc/src/v1/tests/mocked/eth.rs
new file mode 100644
index 000000000..d52fc9f4c
--- /dev/null
+++ b/rpc/src/v1/tests/mocked/eth.rs
@@ -0,0 +1,724 @@
+// 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 .
+
+use std::str::FromStr;
+use std::collections::HashMap;
+use std::sync::{Arc, RwLock};
+use jsonrpc_core::IoHandler;
+use util::hash::{Address, H256, FixedHash};
+use util::numbers::{Uint, U256};
+use util::keys::{TestAccount, TestAccountProvider};
+use ethcore::client::{TestBlockChainClient, EachBlockWith, Executed, TransactionID};
+use ethcore::log_entry::{LocalizedLogEntry, LogEntry};
+use ethcore::receipt::LocalizedReceipt;
+use ethcore::transaction::{Transaction, Action};
+use ethminer::ExternalMiner;
+use v1::{Eth, EthClient};
+use v1::tests::helpers::{TestSyncProvider, Config, TestMinerService};
+
+fn blockchain_client() -> Arc {
+ let client = TestBlockChainClient::new();
+ Arc::new(client)
+}
+
+fn accounts_provider() -> Arc {
+ let mut accounts = HashMap::new();
+ accounts.insert(Address::from(1), TestAccount::new("test"));
+ let ap = TestAccountProvider::new(accounts);
+ Arc::new(ap)
+}
+
+fn sync_provider() -> Arc {
+ Arc::new(TestSyncProvider::new(Config {
+ network_id: U256::from(3),
+ num_peers: 120,
+ }))
+}
+
+fn miner_service() -> Arc {
+ Arc::new(TestMinerService::default())
+}
+
+struct EthTester {
+ pub client: Arc,
+ pub sync: Arc,
+ pub accounts_provider: Arc,
+ miner: Arc,
+ hashrates: Arc>>,
+ pub io: IoHandler,
+}
+
+impl Default for EthTester {
+ fn default() -> Self {
+ let client = blockchain_client();
+ let sync = sync_provider();
+ let ap = accounts_provider();
+ let miner = miner_service();
+ let hashrates = Arc::new(RwLock::new(HashMap::new()));
+ let external_miner = Arc::new(ExternalMiner::new(hashrates.clone()));
+ let eth = EthClient::new(&client, &sync, &ap, &miner, &external_miner).to_delegate();
+ let io = IoHandler::new();
+ io.add_delegate(eth);
+ EthTester {
+ client: client,
+ sync: sync,
+ accounts_provider: ap,
+ miner: miner,
+ io: io,
+ hashrates: hashrates,
+ }
+ }
+}
+
+#[test]
+fn rpc_eth_protocol_version() {
+ let request = r#"{"jsonrpc": "2.0", "method": "eth_protocolVersion", "params": [], "id": 1}"#;
+ let response = r#"{"jsonrpc":"2.0","result":"63","id":1}"#;
+
+ assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
+}
+
+#[test]
+#[ignore]
+fn rpc_eth_syncing() {
+ unimplemented!()
+}
+
+#[test]
+fn rpc_eth_hashrate() {
+ let tester = EthTester::default();
+ tester.hashrates.write().unwrap().insert(H256::from(0), U256::from(0xfffa));
+ tester.hashrates.write().unwrap().insert(H256::from(0), U256::from(0xfffb));
+ tester.hashrates.write().unwrap().insert(H256::from(1), U256::from(0x1));
+
+ let request = r#"{"jsonrpc": "2.0", "method": "eth_hashrate", "params": [], "id": 1}"#;
+ let response = r#"{"jsonrpc":"2.0","result":"0xfffc","id":1}"#;
+
+ assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
+}
+
+#[test]
+fn rpc_eth_submit_hashrate() {
+ let tester = EthTester::default();
+
+ let request = r#"{
+ "jsonrpc": "2.0",
+ "method": "eth_submitHashrate",
+ "params": [
+ "0x0000000000000000000000000000000000000000000000000000000000500000",
+ "0x59daa26581d0acd1fce254fb7e85952f4c09d0915afd33d3886cd914bc7d283c"],
+ "id": 1
+ }"#;
+ let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
+
+ assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
+ assert_eq!(tester.hashrates.read().unwrap().get(&H256::from("0x59daa26581d0acd1fce254fb7e85952f4c09d0915afd33d3886cd914bc7d283c")).cloned(),
+ Some(U256::from(0x500_000)));
+}
+
+#[test]
+#[ignore]
+fn rpc_eth_author() {
+ unimplemented!()
+}
+
+#[test]
+fn rpc_eth_mining() {
+ let tester = EthTester::default();
+
+ let request = r#"{"jsonrpc": "2.0", "method": "eth_mining", "params": [], "id": 1}"#;
+ let response = r#"{"jsonrpc":"2.0","result":false,"id":1}"#;
+ assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
+
+ tester.hashrates.write().unwrap().insert(H256::from(1), U256::from(0x1));
+
+ let request = r#"{"jsonrpc": "2.0", "method": "eth_mining", "params": [], "id": 1}"#;
+ let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#;
+ assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
+}
+
+#[test]
+fn rpc_eth_gas_price() {
+ let request = r#"{"jsonrpc": "2.0", "method": "eth_gasPrice", "params": [], "id": 1}"#;
+ let response = r#"{"jsonrpc":"2.0","result":"0x04a817c800","id":1}"#;
+
+ assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
+}
+
+#[test]
+fn rpc_eth_accounts() {
+ let request = r#"{"jsonrpc": "2.0", "method": "eth_accounts", "params": [], "id": 1}"#;
+ let response = r#"{"jsonrpc":"2.0","result":["0x0000000000000000000000000000000000000001"],"id":1}"#;
+
+ assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
+}
+
+#[test]
+fn rpc_eth_block_number() {
+ let tester = EthTester::default();
+ tester.client.add_blocks(10, EachBlockWith::Nothing);
+
+ let request = r#"{"jsonrpc": "2.0", "method": "eth_blockNumber", "params": [], "id": 1}"#;
+ let response = r#"{"jsonrpc":"2.0","result":"0x0a","id":1}"#;
+
+ assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
+}
+
+#[test]
+fn rpc_eth_balance() {
+ let tester = EthTester::default();
+ tester.client.set_balance(Address::from(1), U256::from(5));
+
+ let request = r#"{
+ "jsonrpc": "2.0",
+ "method": "eth_getBalance",
+ "params": ["0x0000000000000000000000000000000000000001", "latest"],
+ "id": 1
+ }"#;
+ let response = r#"{"jsonrpc":"2.0","result":"0x05","id":1}"#;
+
+ assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
+}
+
+#[ignore] //TODO: propert test
+#[test]
+fn rpc_eth_balance_pending() {
+ let tester = EthTester::default();
+
+ let request = r#"{
+ "jsonrpc": "2.0",
+ "method": "eth_getBalance",
+ "params": ["0x0000000000000000000000000000000000000001", "latest"],
+ "id": 1
+ }"#;
+ let response = r#"{"jsonrpc":"2.0","result":"0x","id":1}"#;
+
+ assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
+}
+
+#[test]
+fn rpc_eth_storage_at() {
+ let tester = EthTester::default();
+ tester.client.set_storage(Address::from(1), H256::from(4), H256::from(7));
+
+ let request = r#"{
+ "jsonrpc": "2.0",
+ "method": "eth_getStorageAt",
+ "params": ["0x0000000000000000000000000000000000000001", "0x4", "latest"],
+ "id": 1
+ }"#;
+ let response = r#"{"jsonrpc":"2.0","result":"0x07","id":1}"#;
+
+ assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
+}
+
+#[test]
+fn rpc_eth_transaction_count() {
+ let request = r#"{
+ "jsonrpc": "2.0",
+ "method": "eth_getTransactionCount",
+ "params": ["0x0000000000000000000000000000000000000001", "latest"],
+ "id": 1
+ }"#;
+ let response = r#"{"jsonrpc":"2.0","result":"0x00","id":1}"#;
+
+ assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
+}
+
+#[test]
+fn rpc_eth_block_transaction_count_by_hash() {
+ let request = r#"{
+ "jsonrpc": "2.0",
+ "method": "eth_getBlockTransactionCountByHash",
+ "params": ["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"],
+ "id": 1
+ }"#;
+ let response = r#"{"jsonrpc":"2.0","result":null,"id":1}"#;
+
+ assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
+}
+
+#[test]
+fn rpc_eth_transaction_count_by_number() {
+ let request = r#"{
+ "jsonrpc": "2.0",
+ "method": "eth_getBlockTransactionCountByNumber",
+ "params": ["latest"],
+ "id": 1
+ }"#;
+ let response = r#"{"jsonrpc":"2.0","result":"0x00","id":1}"#;
+
+ assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
+}
+
+#[test]
+fn rpc_eth_transaction_count_by_number_pending() {
+ let request = r#"{
+ "jsonrpc": "2.0",
+ "method": "eth_getBlockTransactionCountByNumber",
+ "params": ["pending"],
+ "id": 1
+ }"#;
+ let response = r#"{"jsonrpc":"2.0","result":"0x01","id":1}"#;
+
+ assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
+}
+
+#[test]
+fn rpc_eth_pending_transaction_by_hash() {
+ use util::*;
+ use ethcore::transaction::*;
+
+ let tester = EthTester::default();
+ {
+ let tx: SignedTransaction = decode(&FromHex::from_hex("f85f800182520894095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap());
+ tester.miner.pending_transactions.lock().unwrap().insert(H256::zero(), tx);
+ }
+
+ let response = r#"{"jsonrpc":"2.0","result":{"blockHash":null,"blockNumber":null,"from":"0x0f65fe9276bc9a24ae7083ae28e2660ef72df99e","gas":"0x5208","gasPrice":"0x01","hash":"0x41df922fd0d4766fcc02e161f8295ec28522f329ae487f14d811e4b64c8d6e31","input":"0x","nonce":"0x00","to":"0x095e7baea6a6c7c4c2dfeb977efac326af552d87","transactionIndex":null,"value":"0x0a"},"id":1}"#;
+ let request = r#"{
+ "jsonrpc": "2.0",
+ "method": "eth_getTransactionByHash",
+ "params": ["0x0000000000000000000000000000000000000000000000000000000000000000"],
+ "id": 1
+ }"#;
+ assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
+}
+
+
+#[test]
+fn rpc_eth_uncle_count_by_block_hash() {
+ let request = r#"{
+ "jsonrpc": "2.0",
+ "method": "eth_getUncleCountByBlockHash",
+ "params": ["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"],
+ "id": 1
+ }"#;
+ let response = r#"{"jsonrpc":"2.0","result":null,"id":1}"#;
+
+ assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
+}
+
+#[test]
+fn rpc_eth_uncle_count_by_block_number() {
+ let request = r#"{
+ "jsonrpc": "2.0",
+ "method": "eth_getUncleCountByBlockNumber",
+ "params": ["latest"],
+ "id": 1
+ }"#;
+ let response = r#"{"jsonrpc":"2.0","result":"0x00","id":1}"#;
+
+ assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
+}
+
+#[test]
+fn rpc_eth_code() {
+ let tester = EthTester::default();
+ tester.client.set_code(Address::from(1), vec![0xff, 0x21]);
+
+ let request = r#"{
+ "jsonrpc": "2.0",
+ "method": "eth_getCode",
+ "params": ["0x0000000000000000000000000000000000000001", "latest"],
+ "id": 1
+ }"#;
+ let response = r#"{"jsonrpc":"2.0","result":"0xff21","id":1}"#;
+
+ assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
+}
+
+#[test]
+fn rpc_eth_call() {
+ let tester = EthTester::default();
+ tester.client.set_execution_result(Executed {
+ gas: U256::zero(),
+ gas_used: U256::from(0xff30),
+ refunded: U256::from(0x5),
+ cumulative_gas_used: U256::zero(),
+ logs: vec![],
+ contracts_created: vec![],
+ output: vec![0x12, 0x34, 0xff],
+ trace: None,
+ });
+
+ let request = r#"{
+ "jsonrpc": "2.0",
+ "method": "eth_call",
+ "params": [{
+ "from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155",
+ "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
+ "gas": "0x76c0",
+ "gasPrice": "0x9184e72a000",
+ "value": "0x9184e72a",
+ "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
+ },
+ "latest"],
+ "id": 1
+ }"#;
+ let response = r#"{"jsonrpc":"2.0","result":"0x1234ff","id":1}"#;
+
+ assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
+}
+
+#[test]
+fn rpc_eth_call_default_block() {
+ let tester = EthTester::default();
+ tester.client.set_execution_result(Executed {
+ gas: U256::zero(),
+ gas_used: U256::from(0xff30),
+ refunded: U256::from(0x5),
+ cumulative_gas_used: U256::zero(),
+ logs: vec![],
+ contracts_created: vec![],
+ output: vec![0x12, 0x34, 0xff],
+ trace: None,
+ });
+
+ let request = r#"{
+ "jsonrpc": "2.0",
+ "method": "eth_call",
+ "params": [{
+ "from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155",
+ "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
+ "gas": "0x76c0",
+ "gasPrice": "0x9184e72a000",
+ "value": "0x9184e72a",
+ "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
+ }],
+ "id": 1
+ }"#;
+ let response = r#"{"jsonrpc":"2.0","result":"0x1234ff","id":1}"#;
+
+ assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
+}
+
+#[test]
+fn rpc_eth_estimate_gas() {
+ let tester = EthTester::default();
+ tester.client.set_execution_result(Executed {
+ gas: U256::zero(),
+ gas_used: U256::from(0xff30),
+ refunded: U256::from(0x5),
+ cumulative_gas_used: U256::zero(),
+ logs: vec![],
+ contracts_created: vec![],
+ output: vec![0x12, 0x34, 0xff],
+ trace: None,
+ });
+
+ let request = r#"{
+ "jsonrpc": "2.0",
+ "method": "eth_estimateGas",
+ "params": [{
+ "from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155",
+ "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
+ "gas": "0x76c0",
+ "gasPrice": "0x9184e72a000",
+ "value": "0x9184e72a",
+ "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
+ },
+ "latest"],
+ "id": 1
+ }"#;
+ let response = r#"{"jsonrpc":"2.0","result":"0xff35","id":1}"#;
+
+ assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
+}
+
+#[test]
+fn rpc_eth_estimate_gas_default_block() {
+ let tester = EthTester::default();
+ tester.client.set_execution_result(Executed {
+ gas: U256::zero(),
+ gas_used: U256::from(0xff30),
+ refunded: U256::from(0x5),
+ cumulative_gas_used: U256::zero(),
+ logs: vec![],
+ contracts_created: vec![],
+ output: vec![0x12, 0x34, 0xff],
+ trace: None,
+ });
+
+ let request = r#"{
+ "jsonrpc": "2.0",
+ "method": "eth_estimateGas",
+ "params": [{
+ "from": "0xb60e8dd61c5d32be8058bb8eb970870f07233155",
+ "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
+ "gas": "0x76c0",
+ "gasPrice": "0x9184e72a000",
+ "value": "0x9184e72a",
+ "data": "0xd46e8dd67c5d32be8d46e8dd67c5d32be8058bb8eb970870f072445675058bb8eb970870f072445675"
+ }],
+ "id": 1
+ }"#;
+ let response = r#"{"jsonrpc":"2.0","result":"0xff35","id":1}"#;
+
+ assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
+}
+
+#[test]
+fn rpc_eth_send_transaction() {
+ let account = TestAccount::new("123");
+ let address = account.address();
+ let secret = account.secret.clone();
+
+ let tester = EthTester::default();
+ tester.accounts_provider.accounts.write().unwrap().insert(address.clone(), account);
+ let request = r#"{
+ "jsonrpc": "2.0",
+ "method": "eth_sendTransaction",
+ "params": [{
+ "from": ""#.to_owned() + format!("0x{:?}", address).as_ref() + r#"",
+ "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
+ "gas": "0x76c0",
+ "gasPrice": "0x9184e72a000",
+ "value": "0x9184e72a"
+ }],
+ "id": 1
+ }"#;
+
+ let t = Transaction {
+ nonce: U256::zero(),
+ gas_price: U256::from(0x9184e72a000u64),
+ gas: U256::from(0x76c0),
+ action: Action::Call(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()),
+ value: U256::from(0x9184e72au64),
+ data: vec![]
+ }.sign(&secret);
+
+ let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:?}", t.hash()).as_ref() + r#"","id":1}"#;
+
+ assert_eq!(tester.io.handle_request(request.as_ref()), Some(response));
+
+ tester.miner.last_nonces.write().unwrap().insert(address.clone(), U256::zero());
+
+ let t = Transaction {
+ nonce: U256::one(),
+ gas_price: U256::from(0x9184e72a000u64),
+ gas: U256::from(0x76c0),
+ action: Action::Call(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()),
+ value: U256::from(0x9184e72au64),
+ data: vec![]
+ }.sign(&secret);
+
+ let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:?}", t.hash()).as_ref() + r#"","id":1}"#;
+
+ assert_eq!(tester.io.handle_request(request.as_ref()), Some(response));
+}
+
+#[test]
+fn rpc_eth_sign_and_send_transaction_with_invalid_password() {
+ let account = TestAccount::new("password123");
+ let address = account.address();
+
+ let tester = EthTester::default();
+ tester.accounts_provider.accounts.write().unwrap().insert(address.clone(), account);
+ let request = r#"{
+ "jsonrpc": "2.0",
+ "method": "eth_signAndSendTransaction",
+ "params": [{
+ "from": ""#.to_owned() + format!("0x{:?}", address).as_ref() + r#"",
+ "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
+ "gas": "0x76c0",
+ "gasPrice": "0x9184e72a000",
+ "value": "0x9184e72a"
+ }, "password321"],
+ "id": 1
+ }"#;
+
+ let response = r#"{"jsonrpc":"2.0","result":"0x0000000000000000000000000000000000000000000000000000000000000000","id":1}"#;
+
+ assert_eq!(tester.io.handle_request(request.as_ref()), Some(response.into()));
+}
+
+#[test]
+fn rpc_eth_sign_and_send_transaction() {
+ let account = TestAccount::new("password123");
+ let address = account.address();
+ let secret = account.secret.clone();
+
+ let tester = EthTester::default();
+ tester.accounts_provider.accounts.write().unwrap().insert(address.clone(), account);
+ let request = r#"{
+ "jsonrpc": "2.0",
+ "method": "eth_signAndSendTransaction",
+ "params": [{
+ "from": ""#.to_owned() + format!("0x{:?}", address).as_ref() + r#"",
+ "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
+ "gas": "0x76c0",
+ "gasPrice": "0x9184e72a000",
+ "value": "0x9184e72a"
+ }, "password123"],
+ "id": 1
+ }"#;
+
+ let t = Transaction {
+ nonce: U256::zero(),
+ gas_price: U256::from(0x9184e72a000u64),
+ gas: U256::from(0x76c0),
+ action: Action::Call(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()),
+ value: U256::from(0x9184e72au64),
+ data: vec![]
+ }.sign(&secret);
+
+ let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:?}", t.hash()).as_ref() + r#"","id":1}"#;
+
+ assert_eq!(tester.io.handle_request(request.as_ref()), Some(response));
+
+ tester.miner.last_nonces.write().unwrap().insert(address.clone(), U256::zero());
+
+ let t = Transaction {
+ nonce: U256::one(),
+ gas_price: U256::from(0x9184e72a000u64),
+ gas: U256::from(0x76c0),
+ action: Action::Call(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()),
+ value: U256::from(0x9184e72au64),
+ data: vec![]
+ }.sign(&secret);
+
+ let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:?}", t.hash()).as_ref() + r#"","id":1}"#;
+
+ assert_eq!(tester.io.handle_request(request.as_ref()), Some(response));
+}
+
+#[test]
+#[ignore]
+fn rpc_eth_send_raw_transaction() {
+ unimplemented!()
+}
+
+#[test]
+#[ignore]
+fn rpc_eth_sign() {
+ unimplemented!()
+}
+
+#[test]
+fn rpc_eth_transaction_receipt() {
+ let receipt = LocalizedReceipt {
+ transaction_hash: H256::zero(),
+ transaction_index: 0,
+ block_hash: H256::from_str("ed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5").unwrap(),
+ block_number: 0x4510c,
+ cumulative_gas_used: U256::from(0x20),
+ gas_used: U256::from(0x10),
+ contract_address: None,
+ logs: vec![LocalizedLogEntry {
+ entry: LogEntry {
+ address: Address::from_str("33990122638b9132ca29c723bdf037f1a891a70c").unwrap(),
+ topics: vec![
+ H256::from_str("a6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc").unwrap(),
+ H256::from_str("4861736852656700000000000000000000000000000000000000000000000000").unwrap()
+ ],
+ data: vec![],
+ },
+ block_hash: H256::from_str("ed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5").unwrap(),
+ block_number: 0x4510c,
+ transaction_hash: H256::new(),
+ transaction_index: 0,
+ log_index: 1,
+ }]
+ };
+
+ let hash = H256::from_str("b903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238").unwrap();
+ let tester = EthTester::default();
+ tester.client.set_transaction_receipt(TransactionID::Hash(hash), receipt);
+
+ let request = r#"{
+ "jsonrpc": "2.0",
+ "method": "eth_getTransactionReceipt",
+ "params": ["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"],
+ "id": 1
+ }"#;
+ let response = r#"{"jsonrpc":"2.0","result":{"blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x04510c","contractAddress":null,"cumulativeGasUsed":"0x20","gasUsed":"0x10","logs":[{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x04510c","data":"0x","logIndex":"0x01","topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x00","type":"mined"}],"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x00"},"id":1}"#;
+
+ assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
+}
+
+#[test]
+fn rpc_eth_transaction_receipt_null() {
+ let tester = EthTester::default();
+
+ let request = r#"{
+ "jsonrpc": "2.0",
+ "method": "eth_getTransactionReceipt",
+ "params": ["0xb903239f8543d04b5dc1ba6579132b143087c68db1b2168786408fcbce568238"],
+ "id": 1
+ }"#;
+ let response = r#"{"jsonrpc":"2.0","result":null,"id":1}"#;
+
+ assert_eq!(tester.io.handle_request(request), Some(response.to_owned()));
+}
+
+#[test]
+fn rpc_eth_compilers() {
+ let request = r#"{"jsonrpc": "2.0", "method": "eth_getCompilers", "params": [], "id": 1}"#;
+ let response = r#"{"jsonrpc":"2.0","result":[],"id":1}"#;
+
+ assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
+}
+
+#[test]
+fn rpc_eth_compile_lll() {
+ let request = r#"{"jsonrpc": "2.0", "method": "eth_compileLLL", "params": [], "id": 1}"#;
+ let response = r#"{"jsonrpc":"2.0","error":{"code":-32603,"message":"Internal error","data":null},"id":1}"#;
+
+ assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
+}
+
+#[test]
+fn rpc_eth_compile_solidity() {
+ let request = r#"{"jsonrpc": "2.0", "method": "eth_compileSolidity", "params": [], "id": 1}"#;
+ let response = r#"{"jsonrpc":"2.0","error":{"code":-32603,"message":"Internal error","data":null},"id":1}"#;
+
+ assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
+}
+
+#[test]
+fn rpc_eth_compile_serpent() {
+ let request = r#"{"jsonrpc": "2.0", "method": "eth_compileSerpent", "params": [], "id": 1}"#;
+ let response = r#"{"jsonrpc":"2.0","error":{"code":-32603,"message":"Internal error","data":null},"id":1}"#;
+
+ assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned()));
+}
+
+#[test]
+fn returns_no_work_if_cant_mine() {
+ let eth_tester = EthTester::default();
+ eth_tester.client.set_queue_size(10);
+
+ let request = r#"{"jsonrpc": "2.0", "method": "eth_getWork", "params": [], "id": 1}"#;
+ let response = r#"{"jsonrpc":"2.0","result":["","",""],"id":1}"#;
+
+ assert_eq!(eth_tester.io.handle_request(request), Some(response.to_owned()));
+}
+
+#[ignore]
+// enable once TestMinerService supports the mining API.
+#[test]
+fn returns_error_if_can_mine_and_no_closed_block() {
+ use ethsync::{SyncState};
+
+ let eth_tester = EthTester::default();
+ eth_tester.sync.status.write().unwrap().state = SyncState::Idle;
+
+ let request = r#"{"jsonrpc": "2.0", "method": "eth_getWork", "params": [], "id": 1}"#;
+ let response = r#"{"jsonrpc":"2.0","error":{"code":-32603,"message":"Internal error","data":null},"id":1}"#;
+
+ assert_eq!(eth_tester.io.handle_request(request), Some(response.to_owned()));
+}
diff --git a/rpc/src/v1/tests/ethcore.rs b/rpc/src/v1/tests/mocked/ethcore.rs
similarity index 100%
rename from rpc/src/v1/tests/ethcore.rs
rename to rpc/src/v1/tests/mocked/ethcore.rs
diff --git a/rpc/src/v1/tests/mocked/mod.rs b/rpc/src/v1/tests/mocked/mod.rs
new file mode 100644
index 000000000..98caf6e08
--- /dev/null
+++ b/rpc/src/v1/tests/mocked/mod.rs
@@ -0,0 +1,24 @@
+// 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 .
+
+//! RPC serialization tests.
+
+mod eth;
+mod net;
+mod web3;
+mod personal;
+mod ethcore;
+mod rpc;
diff --git a/rpc/src/v1/tests/net.rs b/rpc/src/v1/tests/mocked/net.rs
similarity index 100%
rename from rpc/src/v1/tests/net.rs
rename to rpc/src/v1/tests/mocked/net.rs
diff --git a/rpc/src/v1/tests/personal.rs b/rpc/src/v1/tests/mocked/personal.rs
similarity index 100%
rename from rpc/src/v1/tests/personal.rs
rename to rpc/src/v1/tests/mocked/personal.rs
diff --git a/rpc/src/v1/tests/rpc.rs b/rpc/src/v1/tests/mocked/rpc.rs
similarity index 100%
rename from rpc/src/v1/tests/rpc.rs
rename to rpc/src/v1/tests/mocked/rpc.rs
diff --git a/rpc/src/v1/tests/web3.rs b/rpc/src/v1/tests/mocked/web3.rs
similarity index 100%
rename from rpc/src/v1/tests/web3.rs
rename to rpc/src/v1/tests/mocked/web3.rs
diff --git a/rpc/src/v1/tests/mod.rs b/rpc/src/v1/tests/mod.rs
index 04e0dc142..f5e7d1404 100644
--- a/rpc/src/v1/tests/mod.rs
+++ b/rpc/src/v1/tests/mod.rs
@@ -1,31 +1,8 @@
-// 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 .
-
-//!TODO: load custom blockchain state and test
+//! RPC unit test moduleS
pub mod helpers;
+
#[cfg(test)]
-mod eth;
+mod mocked;
#[cfg(test)]
-mod net;
-#[cfg(test)]
-mod web3;
-#[cfg(test)]
-mod personal;
-#[cfg(test)]
-mod ethcore;
-#[cfg(test)]
-mod rpc;
+mod eth;
\ No newline at end of file
diff --git a/signer/Cargo.toml b/signer/Cargo.toml
new file mode 100644
index 000000000..f72865f4f
--- /dev/null
+++ b/signer/Cargo.toml
@@ -0,0 +1,21 @@
+[package]
+description = "Ethcore Trusted Signer"
+homepage = "http://ethcore.io"
+license = "GPL-3.0"
+name = "ethcore-signer"
+version = "1.2.0"
+authors = ["Ethcore "]
+build = "build.rs"
+
+[build-dependencies]
+rustc_version = "0.1"
+
+[dependencies]
+ethcore-util = { path = "../util" }
+log = "0.3"
+env_logger = "0.3"
+clippy = { version = "0.0.69", optional = true}
+
+[features]
+default = []
+dev = ["clippy"]
diff --git a/signer/build.rs b/signer/build.rs
new file mode 100644
index 000000000..41b9a1b3e
--- /dev/null
+++ b/signer/build.rs
@@ -0,0 +1,25 @@
+// 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 .
+
+extern crate rustc_version;
+
+use rustc_version::{version_meta, Channel};
+
+fn main() {
+ if let Channel::Nightly = version_meta().channel {
+ println!("cargo:rustc-cfg=nightly");
+ }
+}
diff --git a/signer/src/lib.rs b/signer/src/lib.rs
new file mode 100644
index 000000000..fd17758d2
--- /dev/null
+++ b/signer/src/lib.rs
@@ -0,0 +1,41 @@
+// 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 .
+
+#![warn(missing_docs)]
+#![cfg_attr(all(nightly, feature="dev"), feature(plugin))]
+#![cfg_attr(all(nightly, feature="dev"), plugin(clippy))]
+
+//! Signer module
+//!
+//! This module manages your private keys and accounts/identities
+//! that can be used within Dapps.
+//!
+//! It exposes API (over `WebSockets`) accessed by System UIs.
+//! Each transaction sent by Dapp is broadcasted to System UIs
+//! and their responsibility is to confirm (or confirm and sign)
+//! the transaction for you.
+//!
+//!
+
+#[macro_use]
+extern crate log;
+extern crate env_logger;
+
+#[cfg(test)]
+mod tests {
+ #[test]
+ fn should_work() {}
+}
diff --git a/test.sh b/test.sh
index 786ae2b37..e70718afc 100755
--- a/test.sh
+++ b/test.sh
@@ -7,6 +7,7 @@ cargo test --features ethcore/json-tests $1 \
-p ethcore \
-p ethsync \
-p ethcore-rpc \
+ -p ethcore-signer \
-p ethcore-dapps \
-p parity \
-p ethminer \
diff --git a/util/src/journaldb/archivedb.rs b/util/src/journaldb/archivedb.rs
index 4fa8ce6f3..b554db885 100644
--- a/util/src/journaldb/archivedb.rs
+++ b/util/src/journaldb/archivedb.rs
@@ -47,7 +47,9 @@ impl ArchiveDB {
/// Create a new instance from file
pub fn new(path: &str) -> ArchiveDB {
let opts = DatabaseConfig {
- prefix_size: Some(12) //use 12 bytes as prefix, this must match account_db prefix
+ //use 12 bytes as prefix, this must match account_db prefix
+ prefix_size: Some(12),
+ max_open_files: 256,
};
let backing = Database::open(&opts, path).unwrap_or_else(|e| {
panic!("Error opening state db: {}", e);
diff --git a/util/src/journaldb/earlymergedb.rs b/util/src/journaldb/earlymergedb.rs
index 62fe0023a..7cb117447 100644
--- a/util/src/journaldb/earlymergedb.rs
+++ b/util/src/journaldb/earlymergedb.rs
@@ -77,7 +77,9 @@ impl EarlyMergeDB {
/// Create a new instance from file
pub fn new(path: &str) -> EarlyMergeDB {
let opts = DatabaseConfig {
- prefix_size: Some(12) //use 12 bytes as prefix, this must match account_db prefix
+ //use 12 bytes as prefix, this must match account_db prefix
+ prefix_size: Some(12),
+ max_open_files: 256,
};
let backing = Database::open(&opts, path).unwrap_or_else(|e| {
panic!("Error opening state db: {}", e);
diff --git a/util/src/journaldb/overlayrecentdb.rs b/util/src/journaldb/overlayrecentdb.rs
index 9c68b9255..86d8d5c4d 100644
--- a/util/src/journaldb/overlayrecentdb.rs
+++ b/util/src/journaldb/overlayrecentdb.rs
@@ -107,7 +107,9 @@ impl OverlayRecentDB {
/// Create a new instance from file
pub fn from_prefs(path: &str) -> OverlayRecentDB {
let opts = DatabaseConfig {
- prefix_size: Some(12) //use 12 bytes as prefix, this must match account_db prefix
+ //use 12 bytes as prefix, this must match account_db prefix
+ prefix_size: Some(12),
+ max_open_files: 256,
};
let backing = Database::open(&opts, path).unwrap_or_else(|e| {
panic!("Error opening state db: {}", e);
diff --git a/util/src/journaldb/refcounteddb.rs b/util/src/journaldb/refcounteddb.rs
index 0df4d76b1..7f24a729c 100644
--- a/util/src/journaldb/refcounteddb.rs
+++ b/util/src/journaldb/refcounteddb.rs
@@ -49,7 +49,9 @@ impl RefCountedDB {
/// Create a new instance given a `backing` database.
pub fn new(path: &str) -> RefCountedDB {
let opts = DatabaseConfig {
- prefix_size: Some(12) //use 12 bytes as prefix, this must match account_db prefix
+ //use 12 bytes as prefix, this must match account_db prefix
+ prefix_size: Some(12),
+ max_open_files: 256,
};
let backing = Database::open(&opts, path).unwrap_or_else(|e| {
panic!("Error opening state db: {}", e);
diff --git a/util/src/kvdb.rs b/util/src/kvdb.rs
index c0eb7c10c..40b7ef090 100644
--- a/util/src/kvdb.rs
+++ b/util/src/kvdb.rs
@@ -51,7 +51,9 @@ impl DBTransaction {
/// Database configuration
pub struct DatabaseConfig {
/// Optional prefix size in bytes. Allows lookup by partial key.
- pub prefix_size: Option
+ pub prefix_size: Option,
+ /// Max number of open files.
+ pub max_open_files: i32,
}
/// Database iterator
@@ -75,13 +77,13 @@ pub struct Database {
impl Database {
/// Open database with default settings.
pub fn open_default(path: &str) -> Result {
- Database::open(&DatabaseConfig { prefix_size: None }, path)
+ Database::open(&DatabaseConfig { prefix_size: None, max_open_files: 256 }, path)
}
/// Open database file. Creates if it does not exist.
pub fn open(config: &DatabaseConfig, path: &str) -> Result {
let mut opts = Options::new();
- opts.set_max_open_files(256);
+ opts.set_max_open_files(config.max_open_files);
opts.create_if_missing(true);
opts.set_use_fsync(false);
opts.set_compaction_style(DBCompactionStyle::DBUniversalCompaction);
@@ -203,10 +205,10 @@ mod tests {
let path = RandomTempPath::create_dir();
let smoke = Database::open_default(path.as_path().to_str().unwrap()).unwrap();
assert!(smoke.is_empty());
- test_db(&DatabaseConfig { prefix_size: None });
- test_db(&DatabaseConfig { prefix_size: Some(1) });
- test_db(&DatabaseConfig { prefix_size: Some(8) });
- test_db(&DatabaseConfig { prefix_size: Some(32) });
+ test_db(&DatabaseConfig { prefix_size: None, max_open_files: 256 });
+ test_db(&DatabaseConfig { prefix_size: Some(1), max_open_files: 256 });
+ test_db(&DatabaseConfig { prefix_size: Some(8), max_open_files: 256 });
+ test_db(&DatabaseConfig { prefix_size: Some(32), max_open_files: 256 });
}
}