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 }); } }