@@ -21,7 +21,7 @@ use executive::*;
|
||||
use engines::Engine;
|
||||
use env_info::EnvInfo;
|
||||
use evm;
|
||||
use evm::{Schedule, Ext, Factory, Finalize, VMType, ContractCreateResult, MessageCallResult};
|
||||
use evm::{Schedule, Ext, Factory, Finalize, VMType, ContractCreateResult, MessageCallResult, CreateContractAddress};
|
||||
use externalities::*;
|
||||
use types::executed::CallType;
|
||||
use tests::helpers::*;
|
||||
@@ -56,7 +56,8 @@ struct TestExt<'a, T: 'a, V: 'a, B: 'a>
|
||||
{
|
||||
ext: Externalities<'a, T, V, B>,
|
||||
callcreates: Vec<CallCreate>,
|
||||
contract_address: Address
|
||||
nonce: U256,
|
||||
sender: Address,
|
||||
}
|
||||
|
||||
impl<'a, T: 'a, V: 'a, B: 'a> TestExt<'a, T, V, B>
|
||||
@@ -76,9 +77,10 @@ impl<'a, T: 'a, V: 'a, B: 'a> TestExt<'a, T, V, B>
|
||||
vm_tracer: &'a mut V,
|
||||
) -> trie::Result<Self> {
|
||||
Ok(TestExt {
|
||||
contract_address: contract_address(&address, &state.nonce(&address)?),
|
||||
nonce: state.nonce(&address)?,
|
||||
ext: Externalities::new(state, info, engine, vm_factory, depth, origin_info, substate, output, tracer, vm_tracer),
|
||||
callcreates: vec![]
|
||||
callcreates: vec![],
|
||||
sender: address,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -114,14 +116,15 @@ impl<'a, T: 'a, V: 'a, B: 'a> Ext for TestExt<'a, T, V, B>
|
||||
self.ext.blockhash(number)
|
||||
}
|
||||
|
||||
fn create(&mut self, gas: &U256, value: &U256, code: &[u8]) -> ContractCreateResult {
|
||||
fn create(&mut self, gas: &U256, value: &U256, code: &[u8], address: CreateContractAddress) -> ContractCreateResult {
|
||||
self.callcreates.push(CallCreate {
|
||||
data: code.to_vec(),
|
||||
destination: None,
|
||||
gas_limit: *gas,
|
||||
value: *value
|
||||
});
|
||||
ContractCreateResult::Created(self.contract_address.clone(), *gas)
|
||||
let contract_address = contract_address(address, &self.sender, &self.nonce, &code.sha3());
|
||||
ContractCreateResult::Created(contract_address, *gas)
|
||||
}
|
||||
|
||||
fn call(&mut self,
|
||||
|
||||
@@ -21,6 +21,8 @@ use ethereum;
|
||||
use spec::Spec;
|
||||
use ethjson;
|
||||
use ethjson::state::test::ForkSpec;
|
||||
use types::transaction::SignedTransaction;
|
||||
use env_info::EnvInfo;
|
||||
|
||||
lazy_static! {
|
||||
pub static ref FRONTIER: Spec = ethereum::new_frontier_test();
|
||||
@@ -37,7 +39,7 @@ pub fn json_chain_test(json_data: &[u8]) -> Vec<String> {
|
||||
for (name, test) in tests.into_iter() {
|
||||
{
|
||||
let multitransaction = test.transaction;
|
||||
let env = test.env.into();
|
||||
let env: EnvInfo = test.env.into();
|
||||
let pre: PodState = test.pre_state.into();
|
||||
|
||||
for (spec, states) in test.post_states {
|
||||
@@ -54,12 +56,15 @@ pub fn json_chain_test(json_data: &[u8]) -> Vec<String> {
|
||||
let info = format!(" - {} | {:?} ({}/{}) ...", name, spec, i + 1, total);
|
||||
|
||||
let post_root: H256 = state.hash.into();
|
||||
let transaction = multitransaction.select(&state.indexes).into();
|
||||
|
||||
let transaction: SignedTransaction = multitransaction.select(&state.indexes).into();
|
||||
let mut state = get_temp_state();
|
||||
state.populate_from(pre.clone());
|
||||
state.commit().expect(&format!("State test {} failed due to internal error.", name));
|
||||
let _res = state.apply(&env, &**engine, &transaction, false);
|
||||
if transaction.verify_basic(true, None, env.number >= engine.params().eip86_transition).is_ok() {
|
||||
state.commit().expect(&format!("State test {} failed due to internal error.", name));
|
||||
let _res = state.apply(&env, &**engine, &transaction, false);
|
||||
} else {
|
||||
let _rest = state.commit();
|
||||
}
|
||||
if state.root() != &post_root {
|
||||
println!("{} !!! State mismatch (got: {}, expect: {}", info, state.root(), post_root);
|
||||
flushln!("{} fail", info);
|
||||
@@ -73,7 +78,9 @@ pub fn json_chain_test(json_data: &[u8]) -> Vec<String> {
|
||||
|
||||
}
|
||||
|
||||
println!("!!! {:?} tests from failed.", failed.len());
|
||||
if !failed.is_empty() {
|
||||
println!("!!! {:?} tests failed.", failed.len());
|
||||
}
|
||||
failed
|
||||
}
|
||||
|
||||
|
||||
@@ -18,35 +18,37 @@ use super::test_common::*;
|
||||
use evm;
|
||||
use ethjson;
|
||||
use rlp::UntrustedRlp;
|
||||
use transaction::{Action, UnverifiedTransaction};
|
||||
use ethstore::ethkey::public_to_address;
|
||||
use transaction::{Action, UnverifiedTransaction, SignedTransaction};
|
||||
|
||||
fn do_json_test(json_data: &[u8]) -> Vec<String> {
|
||||
let tests = ethjson::transaction::Test::load(json_data).unwrap();
|
||||
let mut failed = Vec::new();
|
||||
let old_schedule = evm::Schedule::new_frontier();
|
||||
let new_schedule = evm::Schedule::new_homestead();
|
||||
let frontier_schedule = evm::Schedule::new_frontier();
|
||||
let homestead_schedule = evm::Schedule::new_homestead();
|
||||
let metropolis_schedule = evm::Schedule::new_metropolis();
|
||||
for (name, test) in tests.into_iter() {
|
||||
let mut fail_unless = |cond: bool, title: &str| if !cond { failed.push(name.clone()); println!("Transaction failed: {:?}: {:?}", name, title); };
|
||||
|
||||
let number: Option<u64> = test.block_number.map(Into::into);
|
||||
let schedule = match number {
|
||||
None => &old_schedule,
|
||||
Some(x) if x < 1_150_000 => &old_schedule,
|
||||
Some(_) => &new_schedule
|
||||
None => &frontier_schedule,
|
||||
Some(x) if x < 1_150_000 => &frontier_schedule,
|
||||
Some(x) if x < 3_000_000 => &homestead_schedule,
|
||||
Some(_) => &metropolis_schedule
|
||||
};
|
||||
let allow_network_id_of_one = number.map_or(false, |n| n >= 2_675_000);
|
||||
let allow_unsigned = number.map_or(false, |n| n >= 3_000_000);
|
||||
|
||||
let rlp: Vec<u8> = test.rlp.into();
|
||||
let res = UntrustedRlp::new(&rlp)
|
||||
.as_val()
|
||||
.map_err(From::from)
|
||||
.and_then(|t: UnverifiedTransaction| t.validate(schedule, schedule.have_delegate_call, allow_network_id_of_one));
|
||||
.and_then(|t: UnverifiedTransaction| t.validate(schedule, schedule.have_delegate_call, allow_network_id_of_one, allow_unsigned));
|
||||
|
||||
fail_unless(test.transaction.is_none() == res.is_err(), "Validity different");
|
||||
if let (Some(tx), Some(sender)) = (test.transaction, test.sender) {
|
||||
let t = res.unwrap();
|
||||
fail_unless(public_to_address(&t.recover_public().unwrap()) == sender.into(), "sender mismatch");
|
||||
fail_unless(SignedTransaction::new(t.clone()).unwrap().sender() == sender.into(), "sender mismatch");
|
||||
let is_acceptable_network_id = match t.network_id() {
|
||||
None => true,
|
||||
Some(1) if allow_network_id_of_one => true,
|
||||
@@ -84,3 +86,7 @@ declare_test!{TransactionTests_Homestead_ttTransactionTestEip155VitaliksTests, "
|
||||
declare_test!{TransactionTests_EIP155_ttTransactionTest, "TransactionTests/EIP155/ttTransactionTest"}
|
||||
declare_test!{TransactionTests_EIP155_ttTransactionTestEip155VitaliksTests, "TransactionTests/EIP155/ttTransactionTestEip155VitaliksTests"}
|
||||
declare_test!{TransactionTests_EIP155_ttTransactionTestVRule, "TransactionTests/EIP155/ttTransactionTestVRule"}
|
||||
|
||||
declare_test!{TransactionTests_Metropolis_ttMetropolisTest, "TransactionTests/Metropolis/ttMetropolisTest"}
|
||||
declare_test!{TransactionTests_Metropolis_ttTransactionTest, "TransactionTests/Metropolis/ttTransactionTest"}
|
||||
declare_test!{TransactionTests_Metropolis_ttTransactionTestZeroSig, "TransactionTests/Metropolis/ttTransactionTestZeroSig"}
|
||||
|
||||
Reference in New Issue
Block a user