Merge branch 'master' of github.com:ethcore/parity

This commit is contained in:
Gav Wood 2016-05-27 08:29:28 +02:00
commit aa9e4af783
26 changed files with 920 additions and 780 deletions

View File

@ -33,7 +33,7 @@ env:
global: global:
# GH_TOKEN # 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= - 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}" - ARCHIVE_SUFFIX="-${TRAVIS_OS_NAME}-${TRAVIS_TAG}"
- KCOV_FEATURES="" - 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" - 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/ethsync-* &&
$KCOV_CMD target/debug/deps/ethcore_rpc-* && $KCOV_CMD target/debug/deps/ethcore_rpc-* &&
$KCOV_CMD target/debug/deps/ethcore_dapps-* && $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/ethminer-* &&
$KCOV_CMD target/debug/deps/ethjson-* && $KCOV_CMD target/debug/deps/ethjson-* &&
$KCOV_CMD target/debug/parity-* && $KCOV_CMD target/debug/parity-* &&

14
Cargo.lock generated
View File

@ -15,6 +15,7 @@ dependencies = [
"ethcore-ipc-codegen 1.2.0", "ethcore-ipc-codegen 1.2.0",
"ethcore-ipc-nano 1.2.0", "ethcore-ipc-nano 1.2.0",
"ethcore-rpc 1.2.0", "ethcore-rpc 1.2.0",
"ethcore-signer 1.2.0",
"ethcore-util 1.2.0", "ethcore-util 1.2.0",
"ethminer 1.2.0", "ethminer 1.2.0",
"ethsync 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)", "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]] [[package]]
name = "ethcore-util" name = "ethcore-util"
version = "1.2.0" version = "1.2.0"
@ -902,7 +914,7 @@ dependencies = [
[[package]] [[package]]
name = "parity-dapps-wallet" name = "parity-dapps-wallet"
version = "0.5.0" 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 = [ dependencies = [
"parity-dapps 0.3.0 (git+https://github.com/ethcore/parity-dapps-rs.git)", "parity-dapps 0.3.0 (git+https://github.com/ethcore/parity-dapps-rs.git)",
] ]

View File

@ -30,6 +30,7 @@ ethsync = { path = "sync" }
ethminer = { path = "miner" } ethminer = { path = "miner" }
ethcore-devtools = { path = "devtools" } ethcore-devtools = { path = "devtools" }
ethcore-rpc = { path = "rpc", optional = true } ethcore-rpc = { path = "rpc", optional = true }
ethcore-signer = { path = "signer", optional = true }
ethcore-dapps = { path = "dapps", optional = true } ethcore-dapps = { path = "dapps", optional = true }
semver = "0.2" semver = "0.2"
ethcore-ipc-nano = { path = "ipc/nano" } ethcore-ipc-nano = { path = "ipc/nano" }
@ -42,11 +43,11 @@ version = "0.8"
default-features = false default-features = false
[features] [features]
default = ["rpc", "dapps"] default = ["rpc", "dapps", "ethcore-signer"]
rpc = ["ethcore-rpc"] rpc = ["ethcore-rpc"]
dapps = ["ethcore-dapps"] dapps = ["ethcore-dapps"]
dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev", "ethcore-rpc/dev", "ethminer/dev", 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-beta = ["ethcore/json-tests"]
travis-nightly = ["ethcore/json-tests", "dev"] travis-nightly = ["ethcore/json-tests", "dev"]

2
cov.sh
View File

@ -23,6 +23,7 @@ cargo test \
-p ethcore-rpc \ -p ethcore-rpc \
-p parity \ -p parity \
-p ethminer \ -p ethminer \
-p ethcore-signer \
-p ethcore-dapps \ -p ethcore-dapps \
--no-run || exit $? --no-run || exit $?
rm -rf target/coverage 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/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/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_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/ethcore_dapps-*
kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethminer-* kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethminer-*
xdg-open target/coverage/index.html xdg-open target/coverage/index.html

1
doc.sh
View File

@ -7,6 +7,7 @@ cargo doc --no-deps --verbose \
-p ethcore \ -p ethcore \
-p ethsync \ -p ethsync \
-p ethcore-rpc \ -p ethcore-rpc \
-p ethcore-signer \
-p ethcore-dapps \ -p ethcore-dapps \
-p parity \ -p parity \
-p ethminer -p ethminer

1
fmt.sh
View File

@ -9,6 +9,7 @@ $RUSTFMT ./json/src/lib.rs
$RUSTFMT ./miner/src/lib.rs $RUSTFMT ./miner/src/lib.rs
$RUSTFMT ./parity/main.rs $RUSTFMT ./parity/main.rs
$RUSTFMT ./rpc/src/lib.rs $RUSTFMT ./rpc/src/lib.rs
$RUSTFMT ./signer/src/lib.rs
$RUSTFMT ./dapps/src/lib.rs $RUSTFMT ./dapps/src/lib.rs
$RUSTFMT ./sync/src/lib.rs $RUSTFMT ./sync/src/lib.rs
$RUSTFMT ./util/src/lib.rs $RUSTFMT ./util/src/lib.rs

View File

@ -7,6 +7,6 @@ echo "set -e" >> $FILE
echo "cargo build --features dev" >> $FILE echo "cargo build --features dev" >> $FILE
# Build tests # Build tests
echo "cargo test --no-run --features dev \\" >> $FILE 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 echo "" >> $FILE
chmod +x $FILE chmod +x $FILE

View File

@ -14,13 +14,13 @@
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>. // along with Parity. If not, see <http://www.gnu.org/licenses/>.
use std::{fs, env}; use std::fs;
use std::fs::File; use std::fs::File;
use std::io::{Read, Write, Error as IoError, ErrorKind}; use std::io::{Read, Write, Error as IoError, ErrorKind};
use std::path::PathBuf; use std::path::PathBuf;
use std::fmt::{Display, Formatter, Error as FmtError}; use std::fmt::{Display, Formatter, Error as FmtError};
use util::migration::{Manager as MigrationManager, Config as MigrationConfig, MigrationIterator}; use util::migration::{Manager as MigrationManager, Config as MigrationConfig, MigrationIterator};
use util::kvdb::Database; use util::kvdb::{Database, DatabaseConfig};
use ethcore::migrations; use ethcore::migrations;
/// Database is assumed to be at default version, when no version file is found. /// 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. /// Temporary database path used for migration.
fn temp_database_path() -> PathBuf { fn temp_database_path(path: &PathBuf) -> PathBuf {
let mut dir = env::temp_dir(); let mut temp_path = path.clone();
dir.push("parity_migration"); temp_path.pop();
dir 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. /// 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); println!("Migrating database {} from version {} to {}", path.to_string_lossy(), version, CURRENT_VERSION);
// get temp path let temp_path = temp_database_path(&path);
let temp_path = temp_database_path(); let backup_path = backup_database_path(&path);
// remote the dir if it exists // remote the dir if it exists
let _ = fs::remove_dir_all(&temp_path); 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 // 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 // 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 // migrate old database to the new one
try!(migrations.execute(MigrationIterator::from(old.iter()), version, &mut temp).map_err(|_| Error::MigrationFailed)); try!(migrations.execute(MigrationIterator::from(old.iter()), version, &mut temp).map_err(|_| Error::MigrationFailed));
} }
// replace the old database with the new one // create backup
try!(fs::remove_dir_all(&path)); try!(fs::rename(&path, &backup_path));
try!(fs::rename(&temp_path, &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"); println!("Migration finished");
Ok(()) Ok(())

View File

@ -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 <http://www.gnu.org/licenses/>.
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<TestBlockChainClient> {
let client = TestBlockChainClient::new();
Arc::new(client)
}
fn accounts_provider() -> Arc<TestAccountProvider> {
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<TestSyncProvider> {
Arc::new(TestSyncProvider::new(Config {
network_id: U256::from(3),
num_peers: 120,
}))
}
fn miner_service() -> Arc<TestMinerService> {
Arc::new(TestMinerService::default())
}
struct EthTester {
pub client: Arc<TestBlockChainClient>,
pub sync: Arc<TestSyncProvider>,
pub accounts_provider: Arc<TestAccountProvider>,
miner: Arc<TestMinerService>,
hashrates: Arc<RwLock<HashMap<H256, U256>>>,
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()));
}

View File

@ -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 <http://www.gnu.org/licenses/>.
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<TestBlockChainClient> {
let client = TestBlockChainClient::new();
Arc::new(client)
}
fn accounts_provider() -> Arc<TestAccountProvider> {
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<TestSyncProvider> {
Arc::new(TestSyncProvider::new(Config {
network_id: U256::from(3),
num_peers: 120,
}))
}
fn miner_service() -> Arc<TestMinerService> {
Arc::new(TestMinerService::default())
}
struct EthTester {
pub client: Arc<TestBlockChainClient>,
pub sync: Arc<TestSyncProvider>,
pub accounts_provider: Arc<TestAccountProvider>,
miner: Arc<TestMinerService>,
hashrates: Arc<RwLock<HashMap<H256, U256>>>,
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()));
}

View File

@ -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 <http://www.gnu.org/licenses/>.
//! RPC serialization tests.
mod eth;
mod net;
mod web3;
mod personal;
mod ethcore;
mod rpc;

View File

@ -1,31 +1,8 @@
// Copyright 2015, 2016 Ethcore (UK) Ltd. //! RPC unit test moduleS
// This file is part of Parity.
// Parity is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Parity is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
//!TODO: load custom blockchain state and test
pub mod helpers; pub mod helpers;
#[cfg(test)]
mod mocked;
#[cfg(test)] #[cfg(test)]
mod eth; mod eth;
#[cfg(test)]
mod net;
#[cfg(test)]
mod web3;
#[cfg(test)]
mod personal;
#[cfg(test)]
mod ethcore;
#[cfg(test)]
mod rpc;

21
signer/Cargo.toml Normal file
View File

@ -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 <admin@ethcore.io>"]
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"]

25
signer/build.rs Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
extern crate rustc_version;
use rustc_version::{version_meta, Channel};
fn main() {
if let Channel::Nightly = version_meta().channel {
println!("cargo:rustc-cfg=nightly");
}
}

41
signer/src/lib.rs Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
#![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() {}
}

View File

@ -7,6 +7,7 @@ cargo test --features ethcore/json-tests $1 \
-p ethcore \ -p ethcore \
-p ethsync \ -p ethsync \
-p ethcore-rpc \ -p ethcore-rpc \
-p ethcore-signer \
-p ethcore-dapps \ -p ethcore-dapps \
-p parity \ -p parity \
-p ethminer \ -p ethminer \

View File

@ -47,7 +47,9 @@ impl ArchiveDB {
/// Create a new instance from file /// Create a new instance from file
pub fn new(path: &str) -> ArchiveDB { pub fn new(path: &str) -> ArchiveDB {
let opts = DatabaseConfig { 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| { let backing = Database::open(&opts, path).unwrap_or_else(|e| {
panic!("Error opening state db: {}", e); panic!("Error opening state db: {}", e);

View File

@ -77,7 +77,9 @@ impl EarlyMergeDB {
/// Create a new instance from file /// Create a new instance from file
pub fn new(path: &str) -> EarlyMergeDB { pub fn new(path: &str) -> EarlyMergeDB {
let opts = DatabaseConfig { 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| { let backing = Database::open(&opts, path).unwrap_or_else(|e| {
panic!("Error opening state db: {}", e); panic!("Error opening state db: {}", e);

View File

@ -107,7 +107,9 @@ impl OverlayRecentDB {
/// Create a new instance from file /// Create a new instance from file
pub fn from_prefs(path: &str) -> OverlayRecentDB { pub fn from_prefs(path: &str) -> OverlayRecentDB {
let opts = DatabaseConfig { 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| { let backing = Database::open(&opts, path).unwrap_or_else(|e| {
panic!("Error opening state db: {}", e); panic!("Error opening state db: {}", e);

View File

@ -49,7 +49,9 @@ impl RefCountedDB {
/// Create a new instance given a `backing` database. /// Create a new instance given a `backing` database.
pub fn new(path: &str) -> RefCountedDB { pub fn new(path: &str) -> RefCountedDB {
let opts = DatabaseConfig { 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| { let backing = Database::open(&opts, path).unwrap_or_else(|e| {
panic!("Error opening state db: {}", e); panic!("Error opening state db: {}", e);

View File

@ -51,7 +51,9 @@ impl DBTransaction {
/// Database configuration /// Database configuration
pub struct DatabaseConfig { pub struct DatabaseConfig {
/// Optional prefix size in bytes. Allows lookup by partial key. /// Optional prefix size in bytes. Allows lookup by partial key.
pub prefix_size: Option<usize> pub prefix_size: Option<usize>,
/// Max number of open files.
pub max_open_files: i32,
} }
/// Database iterator /// Database iterator
@ -75,13 +77,13 @@ pub struct Database {
impl Database { impl Database {
/// Open database with default settings. /// Open database with default settings.
pub fn open_default(path: &str) -> Result<Database, String> { pub fn open_default(path: &str) -> Result<Database, String> {
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. /// Open database file. Creates if it does not exist.
pub fn open(config: &DatabaseConfig, path: &str) -> Result<Database, String> { pub fn open(config: &DatabaseConfig, path: &str) -> Result<Database, String> {
let mut opts = Options::new(); 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.create_if_missing(true);
opts.set_use_fsync(false); opts.set_use_fsync(false);
opts.set_compaction_style(DBCompactionStyle::DBUniversalCompaction); opts.set_compaction_style(DBCompactionStyle::DBUniversalCompaction);
@ -203,10 +205,10 @@ mod tests {
let path = RandomTempPath::create_dir(); let path = RandomTempPath::create_dir();
let smoke = Database::open_default(path.as_path().to_str().unwrap()).unwrap(); let smoke = Database::open_default(path.as_path().to_str().unwrap()).unwrap();
assert!(smoke.is_empty()); assert!(smoke.is_empty());
test_db(&DatabaseConfig { prefix_size: None }); test_db(&DatabaseConfig { prefix_size: None, max_open_files: 256 });
test_db(&DatabaseConfig { prefix_size: Some(1) }); test_db(&DatabaseConfig { prefix_size: Some(1), max_open_files: 256 });
test_db(&DatabaseConfig { prefix_size: Some(8) }); test_db(&DatabaseConfig { prefix_size: Some(8), max_open_files: 256 });
test_db(&DatabaseConfig { prefix_size: Some(32) }); test_db(&DatabaseConfig { prefix_size: Some(32), max_open_files: 256 });
} }
} }