2016-03-17 11:50:31 +01:00
|
|
|
// 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/>.
|
|
|
|
|
2016-03-17 23:58:30 +01:00
|
|
|
extern crate ctrlc;
|
2016-03-17 11:50:31 +01:00
|
|
|
extern crate docopt;
|
|
|
|
extern crate rustc_serialize;
|
|
|
|
extern crate serde_json;
|
|
|
|
extern crate ethjson;
|
2016-03-17 23:58:30 +01:00
|
|
|
extern crate ethcore_util as util;
|
2016-03-17 15:51:40 +01:00
|
|
|
extern crate ethcore;
|
2016-03-17 23:58:30 +01:00
|
|
|
extern crate ethcore_devtools as devtools;
|
|
|
|
extern crate ethcore_rpc as rpc;
|
2016-03-17 11:50:31 +01:00
|
|
|
|
2016-03-17 23:58:30 +01:00
|
|
|
use std::collections::HashMap;
|
|
|
|
use std::sync::{Arc, Mutex, Condvar};
|
2016-03-17 11:50:31 +01:00
|
|
|
use std::process;
|
|
|
|
use std::fs::File;
|
|
|
|
use std::path::Path;
|
|
|
|
use docopt::Docopt;
|
2016-03-17 23:58:30 +01:00
|
|
|
use ctrlc::CtrlC;
|
2016-03-17 15:51:40 +01:00
|
|
|
use ethcore::spec::Genesis;
|
|
|
|
use ethcore::pod_state::PodState;
|
|
|
|
use ethcore::ethereum;
|
2016-03-17 23:58:30 +01:00
|
|
|
use ethcore::client::{BlockChainClient, Client, ClientConfig};
|
|
|
|
use devtools::RandomTempPath;
|
2016-03-18 18:16:22 +01:00
|
|
|
use util::IoChannel;
|
2016-03-19 11:02:44 +01:00
|
|
|
use rpc::v1::tests::helpers::{TestSyncProvider, Config as SyncConfig, TestMinerService, TestAccountProvider, TestAccount};
|
2016-03-19 12:23:48 +01:00
|
|
|
use rpc::v1::{Eth, EthClient, EthFilter, EthFilterClient};
|
2016-03-17 23:58:30 +01:00
|
|
|
use util::panics::MayPanic;
|
2016-03-19 11:02:44 +01:00
|
|
|
use util::hash::Address;
|
2016-03-17 11:50:31 +01:00
|
|
|
|
|
|
|
const USAGE: &'static str = r#"
|
|
|
|
Parity rpctest client.
|
|
|
|
By Wood/Paronyan/Kotewicz/Drwięga/Volf.
|
|
|
|
Copyright 2015, 2016 Ethcore (UK) Limited
|
|
|
|
|
|
|
|
Usage:
|
2016-03-18 18:08:28 +01:00
|
|
|
rpctest --json <test-file> --name <test-name> [options]
|
|
|
|
rpctest --help
|
2016-03-17 23:58:30 +01:00
|
|
|
|
|
|
|
Options:
|
|
|
|
--jsonrpc-addr HOST Specify the hostname portion of the JSONRPC API
|
|
|
|
server [default: 127.0.0.1].
|
|
|
|
--jsonrpc-port PORT Specify the port portion of the JSONRPC API server
|
|
|
|
[default: 8545].
|
2016-03-17 11:50:31 +01:00
|
|
|
"#;
|
|
|
|
|
|
|
|
#[derive(Debug, RustcDecodable)]
|
|
|
|
struct Args {
|
|
|
|
arg_test_file: String,
|
|
|
|
arg_test_name: String,
|
2016-03-17 23:58:30 +01:00
|
|
|
flag_jsonrpc_addr: String,
|
|
|
|
flag_jsonrpc_port: u16,
|
2016-03-17 11:50:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
struct Configuration {
|
|
|
|
args: Args,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Configuration {
|
|
|
|
fn parse() -> Self {
|
|
|
|
Configuration {
|
|
|
|
args: Docopt::new(USAGE).and_then(|d| d.decode()).unwrap_or_else(|e| e.exit())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn execute(&self) {
|
|
|
|
println!("file path: {:?}", self.args.arg_test_file);
|
|
|
|
println!("test name: {:?}", self.args.arg_test_name);
|
|
|
|
|
|
|
|
let path = Path::new(&self.args.arg_test_file);
|
|
|
|
let file = File::open(path).unwrap_or_else(|_| {
|
|
|
|
println!("Cannot open file.");
|
|
|
|
process::exit(1);
|
|
|
|
});
|
|
|
|
|
2016-03-19 11:02:44 +01:00
|
|
|
let tests: ethjson::blockchain::Test = serde_json::from_reader(file).unwrap_or_else(|err| {
|
2016-03-17 11:50:31 +01:00
|
|
|
println!("Invalid json file.");
|
2016-03-19 11:02:44 +01:00
|
|
|
println!("{:?}", err);
|
2016-03-17 11:50:31 +01:00
|
|
|
process::exit(2);
|
|
|
|
});
|
|
|
|
|
|
|
|
let blockchain = tests.get(&self.args.arg_test_name).unwrap_or_else(|| {
|
|
|
|
println!("Invalid test name.");
|
|
|
|
process::exit(3);
|
|
|
|
});
|
|
|
|
|
2016-03-17 15:51:40 +01:00
|
|
|
let genesis = Genesis::from(blockchain.genesis());
|
|
|
|
let state = PodState::from(blockchain.pre_state.clone());
|
|
|
|
let mut spec = ethereum::new_frontier_test();
|
|
|
|
spec.set_genesis_state(state);
|
|
|
|
spec.overwrite_genesis_params(genesis);
|
|
|
|
assert!(spec.is_state_root_valid());
|
2016-03-17 11:50:31 +01:00
|
|
|
|
2016-03-17 23:58:30 +01:00
|
|
|
let temp = RandomTempPath::new();
|
|
|
|
{
|
|
|
|
let client: Arc<Client> = Client::new(ClientConfig::default(), spec, temp.as_path(), IoChannel::disconnected()).unwrap();
|
|
|
|
for b in &blockchain.blocks_rlp() {
|
|
|
|
let _ = client.import_block(b.clone());
|
|
|
|
client.flush_queue();
|
|
|
|
client.import_verified_blocks(&IoChannel::disconnected());
|
|
|
|
}
|
|
|
|
let sync = Arc::new(TestSyncProvider::new(SyncConfig {
|
|
|
|
protocol_version: 65,
|
|
|
|
num_peers: 120
|
|
|
|
}));
|
|
|
|
|
|
|
|
let miner = Arc::new(TestMinerService::default());
|
2016-03-19 11:02:44 +01:00
|
|
|
let mut accs = HashMap::new();
|
|
|
|
accs.insert(Address::from(1), TestAccount::new("test"));
|
|
|
|
let accounts = Arc::new(TestAccountProvider::new(accs));
|
2016-03-17 23:58:30 +01:00
|
|
|
let server = rpc::RpcServer::new();
|
2016-06-19 14:51:51 +02:00
|
|
|
server.add_delegate(EthClient::new(&client, &sync, &accounts, &miner, true).to_delegate());
|
2016-03-19 12:23:48 +01:00
|
|
|
server.add_delegate(EthFilterClient::new(&client, &miner).to_delegate());
|
2016-03-17 23:58:30 +01:00
|
|
|
|
|
|
|
let url = format!("{}:{}", self.args.flag_jsonrpc_addr, self.args.flag_jsonrpc_port);
|
|
|
|
let panic_handler = server.start_http(url.as_ref(), "*", 1);
|
|
|
|
let exit = Arc::new(Condvar::new());
|
|
|
|
|
|
|
|
let e = exit.clone();
|
|
|
|
CtrlC::set_handler(move || { e.notify_all(); });
|
|
|
|
|
|
|
|
let e = exit.clone();
|
|
|
|
panic_handler.on_panic(move |_reason| { e.notify_all(); });
|
|
|
|
|
|
|
|
let mutex = Mutex::new(());
|
2016-07-13 19:59:59 +02:00
|
|
|
let _ = exit.wait(mutex.lock()).unwrap();
|
2016-03-17 23:58:30 +01:00
|
|
|
}
|
2016-03-17 11:50:31 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
Configuration::parse().execute();
|
|
|
|
}
|