2019-01-07 11:33:07 +01:00
|
|
|
// Copyright 2015-2019 Parity Technologies (UK) Ltd.
|
|
|
|
// This file is part of Parity Ethereum.
|
2016-02-05 13:40:41 +01:00
|
|
|
|
2019-01-07 11:33:07 +01:00
|
|
|
// Parity Ethereum is free software: you can redistribute it and/or modify
|
2016-02-05 13:40:41 +01:00
|
|
|
// 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.
|
|
|
|
|
2019-01-07 11:33:07 +01:00
|
|
|
// Parity Ethereum is distributed in the hope that it will be useful,
|
2016-02-05 13:40:41 +01:00
|
|
|
// 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
|
2019-01-07 11:33:07 +01:00
|
|
|
// along with Parity Ethereum. If not, see <http://www.gnu.org/licenses/>.
|
2016-02-05 13:40:41 +01:00
|
|
|
|
2020-09-08 02:48:09 +02:00
|
|
|
use super::{test_common::*, HookType};
|
2019-02-26 13:49:33 +01:00
|
|
|
use client::{EvmTestClient, EvmTestError, TransactErr, TransactSuccess};
|
2016-03-25 13:08:57 +01:00
|
|
|
use ethjson;
|
2017-04-12 13:33:49 +02:00
|
|
|
use pod_state::PodState;
|
2018-06-25 11:21:45 +02:00
|
|
|
use std::path::Path;
|
2017-08-28 14:25:16 +02:00
|
|
|
use trace;
|
2019-01-04 14:05:46 +01:00
|
|
|
use types::transaction::SignedTransaction;
|
2017-08-01 12:37:57 +02:00
|
|
|
use vm::EnvInfo;
|
2018-06-25 11:21:45 +02:00
|
|
|
|
2020-09-08 02:48:09 +02:00
|
|
|
fn skip_test(
|
|
|
|
test: ðjson::test::StateTests,
|
|
|
|
subname: &str,
|
|
|
|
chain: &String,
|
|
|
|
number: usize,
|
|
|
|
) -> bool {
|
|
|
|
trace!(target: "json-tests", "[state, skip_test] subname: '{}', chain: '{}', number: {}", subname, chain, number);
|
|
|
|
test.skip.iter().any(|state_test| {
|
|
|
|
if let Some(subtest) = state_test.names.get(subname) {
|
|
|
|
trace!(target: "json-tests", "[state, skip_test] Maybe skipping {:?}", subtest);
|
2018-09-25 12:24:40 +02:00
|
|
|
chain == &subtest.chain
|
|
|
|
&& (subtest.subnumbers[0] == "*"
|
|
|
|
|| subtest.subnumbers.contains(&number.to_string()))
|
|
|
|
} else {
|
|
|
|
false
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2018-06-25 11:21:45 +02:00
|
|
|
pub fn json_chain_test<H: FnMut(&str, HookType)>(
|
2020-09-08 02:48:09 +02:00
|
|
|
state_test: ðjson::test::StateTests,
|
|
|
|
path: &Path,
|
2018-06-25 11:21:45 +02:00
|
|
|
json_data: &[u8],
|
|
|
|
start_stop_hook: &mut H,
|
|
|
|
) -> Vec<String> {
|
2019-01-08 15:07:20 +01:00
|
|
|
let _ = ::env_logger::try_init();
|
2020-09-08 02:48:09 +02:00
|
|
|
let tests = ethjson::state::test::Test::load(json_data).expect(&format!(
|
|
|
|
"Could not parse JSON state test data from {}",
|
|
|
|
path.display()
|
|
|
|
));
|
2016-01-13 01:19:05 +01:00
|
|
|
let mut failed = Vec::new();
|
2020-08-05 06:08:03 +02:00
|
|
|
|
2016-03-25 13:08:57 +01:00
|
|
|
for (name, test) in tests.into_iter() {
|
2020-09-10 08:04:14 +02:00
|
|
|
if !super::debug_include_test(&name) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2018-06-25 11:21:45 +02:00
|
|
|
start_stop_hook(&name, HookType::OnStart);
|
2020-08-05 06:08:03 +02:00
|
|
|
|
2016-01-15 04:02:06 +01:00
|
|
|
{
|
2017-04-12 13:33:49 +02:00
|
|
|
let multitransaction = test.transaction;
|
2017-04-19 14:30:00 +02:00
|
|
|
let env: EnvInfo = test.env.into();
|
2016-03-25 13:08:57 +01:00
|
|
|
let pre: PodState = test.pre_state.into();
|
2020-08-05 06:08:03 +02:00
|
|
|
|
2017-08-28 14:25:16 +02:00
|
|
|
for (spec_name, states) in test.post_states {
|
2017-04-12 13:33:49 +02:00
|
|
|
let total = states.len();
|
2017-08-28 14:25:16 +02:00
|
|
|
let spec = match EvmTestClient::spec_from_json(&spec_name) {
|
|
|
|
Some(spec) => spec,
|
|
|
|
None => {
|
2020-09-08 02:48:09 +02:00
|
|
|
panic!(
|
|
|
|
"Unimplemented chainspec '{:?}' in test '{}'",
|
|
|
|
spec_name, name
|
2017-08-28 14:25:16 +02:00
|
|
|
);
|
|
|
|
}
|
2017-04-12 13:33:49 +02:00
|
|
|
};
|
2020-08-05 06:08:03 +02:00
|
|
|
|
2017-04-12 13:33:49 +02:00
|
|
|
for (i, state) in states.into_iter().enumerate() {
|
2020-09-08 02:48:09 +02:00
|
|
|
let info = format!(
|
|
|
|
" - state: {} | {:?} ({}/{}) ...",
|
|
|
|
name,
|
|
|
|
spec_name,
|
|
|
|
i + 1,
|
|
|
|
total
|
|
|
|
);
|
|
|
|
if skip_test(&state_test, &name, &spec.name, i + 1) {
|
|
|
|
println!("{}: SKIPPED", info);
|
2018-09-25 12:24:40 +02:00
|
|
|
continue;
|
|
|
|
}
|
2020-08-05 06:08:03 +02:00
|
|
|
|
2017-04-12 13:33:49 +02:00
|
|
|
let post_root: H256 = state.hash.into();
|
2017-04-19 14:30:00 +02:00
|
|
|
let transaction: SignedTransaction =
|
|
|
|
multitransaction.select(&state.indexes).into();
|
2020-08-05 06:08:03 +02:00
|
|
|
|
2017-08-28 14:25:16 +02:00
|
|
|
let result = || -> Result<_, EvmTestError> {
|
2018-06-25 11:21:45 +02:00
|
|
|
Ok(EvmTestClient::from_pod_state(&spec, pre.clone())?.transact(
|
2018-03-13 12:54:17 +01:00
|
|
|
&env,
|
|
|
|
transaction,
|
|
|
|
trace::NoopTracer,
|
|
|
|
trace::NoopVMTracer,
|
|
|
|
))
|
2017-08-28 14:25:16 +02:00
|
|
|
};
|
|
|
|
match result() {
|
|
|
|
Err(err) => {
|
|
|
|
println!("{} !!! Unexpected internal error: {:?}", info, err);
|
|
|
|
flushln!("{} fail", info);
|
|
|
|
failed.push(name.clone());
|
|
|
|
}
|
2019-02-26 13:49:33 +01:00
|
|
|
Ok(Ok(TransactSuccess { state_root, .. })) if state_root != post_root => {
|
2017-08-28 14:25:16 +02:00
|
|
|
println!(
|
|
|
|
"{} !!! State mismatch (got: {}, expect: {}",
|
|
|
|
info, state_root, post_root
|
|
|
|
);
|
|
|
|
flushln!("{} fail", info);
|
|
|
|
failed.push(name.clone());
|
|
|
|
}
|
2019-02-26 13:49:33 +01:00
|
|
|
Ok(Err(TransactErr {
|
|
|
|
state_root,
|
|
|
|
ref error,
|
|
|
|
..
|
|
|
|
})) if state_root != post_root => {
|
2017-08-28 14:25:16 +02:00
|
|
|
println!(
|
|
|
|
"{} !!! State mismatch (got: {}, expect: {}",
|
|
|
|
info, state_root, post_root
|
|
|
|
);
|
|
|
|
println!("{} !!! Execution error: {:?}", info, error);
|
|
|
|
flushln!("{} fail", info);
|
|
|
|
failed.push(name.clone());
|
|
|
|
}
|
2019-02-26 13:49:33 +01:00
|
|
|
Ok(Err(TransactErr { error, .. })) => {
|
2017-08-28 14:25:16 +02:00
|
|
|
flushln!("{} ok ({:?})", info, error);
|
|
|
|
}
|
|
|
|
Ok(_) => {
|
|
|
|
flushln!("{} ok", info);
|
2016-01-15 01:44:23 +01:00
|
|
|
}
|
2016-01-13 01:19:05 +01:00
|
|
|
}
|
2020-08-05 06:08:03 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-25 11:21:45 +02:00
|
|
|
start_stop_hook(&name, HookType::OnStop);
|
2016-01-13 01:19:05 +01:00
|
|
|
}
|
2020-08-05 06:08:03 +02:00
|
|
|
|
2016-01-13 01:19:05 +01:00
|
|
|
failed
|
|
|
|
}
|