1616
1717use std:: path:: Path ;
1818use super :: test_common:: * ;
19- use evm;
19+ use client:: EvmTestClient ;
20+ use header:: Header ;
2021use ethjson;
2122use rlp:: Rlp ;
22- use transaction:: { Action , UnverifiedTransaction , SignedTransaction } ;
23+ use transaction:: UnverifiedTransaction ;
2324
2425/// Run transaction jsontests on a given folder.
2526pub fn run_test_path < H : FnMut ( & str , HookType ) > ( p : & Path , skip : & [ & ' static str ] , h : & mut H ) {
@@ -31,55 +32,61 @@ pub fn run_test_file<H: FnMut(&str, HookType)>(p: &Path, h: &mut H) {
3132 :: json_tests:: test_common:: run_test_file ( p, do_json_test, h)
3233}
3334
35+ // Block number used to run the tests.
36+ // Make sure that all the specified features are activated.
37+ const BLOCK_NUMBER : u64 = 0x6ffffffffffffe ;
38+
3439fn do_json_test < H : FnMut ( & str , HookType ) > ( json_data : & [ u8 ] , start_stop_hook : & mut H ) -> Vec < String > {
3540 let tests = ethjson:: transaction:: Test :: load ( json_data) . unwrap ( ) ;
3641 let mut failed = Vec :: new ( ) ;
37- let frontier_schedule = evm:: Schedule :: new_frontier ( ) ;
38- let homestead_schedule = evm:: Schedule :: new_homestead ( ) ;
39- let byzantium_schedule = evm:: Schedule :: new_byzantium ( ) ;
4042 for ( name, test) in tests. into_iter ( ) {
4143 start_stop_hook ( & name, HookType :: OnStart ) ;
4244
43- let mut fail_unless = |cond : bool , title : & str | if !cond { failed. push ( name. clone ( ) ) ; println ! ( "Transaction failed: {:?}: {:?}" , name, title) ; } ;
44-
45- let number: Option < u64 > = test. block_number . map ( Into :: into) ;
46- let schedule = match number {
47- None => & frontier_schedule,
48- Some ( x) if x < 1_150_000 => & frontier_schedule,
49- Some ( x) if x < 3_000_000 => & homestead_schedule,
50- Some ( _) => & byzantium_schedule
51- } ;
52- let allow_chain_id_of_one = number. map_or ( false , |n| n >= 2_675_000 ) ;
53- let allow_unsigned = number. map_or ( false , |n| n >= 3_000_000 ) ;
54-
55- let rlp: Vec < u8 > = test. rlp . into ( ) ;
56- let res = Rlp :: new ( & rlp)
57- . as_val ( )
58- . map_err ( :: error:: Error :: from)
59- . and_then ( |t : UnverifiedTransaction | {
60- t. validate ( schedule, schedule. have_delegate_call , allow_chain_id_of_one, allow_unsigned) . map_err ( Into :: into)
61- } ) ;
62-
63- fail_unless ( test. transaction . is_none ( ) == res. is_err ( ) , "Validity different" ) ;
64- if let ( Some ( tx) , Some ( sender) ) = ( test. transaction , test. sender ) {
65- let t = res. unwrap ( ) ;
66- fail_unless ( SignedTransaction :: new ( t. clone ( ) ) . unwrap ( ) . sender ( ) == sender. into ( ) , "sender mismatch" ) ;
67- let is_acceptable_chain_id = match t. chain_id ( ) {
68- None => true ,
69- Some ( 1 ) if allow_chain_id_of_one => true ,
70- _ => false ,
45+ for ( spec_name, result) in test. post_state {
46+ let spec = match EvmTestClient :: spec_from_json ( & spec_name) {
47+ Some ( spec) => spec,
48+ None => {
49+ println ! ( " - {} | {:?} Ignoring tests because of missing spec" , name, spec_name) ;
50+ continue ;
51+ }
52+ } ;
53+
54+ let mut fail_unless = |cond : bool , title : & str | if !cond {
55+ failed. push ( format ! ( "{}-{:?}" , name, spec_name) ) ;
56+ println ! ( "Transaction failed: {:?}-{:?}: {:?}" , name, spec_name, title) ;
7157 } ;
72- fail_unless ( is_acceptable_chain_id, "Network ID unacceptable" ) ;
73- let data: Vec < u8 > = tx. data . into ( ) ;
74- fail_unless ( t. data == data, "data mismatch" ) ;
75- fail_unless ( t. gas_price == tx. gas_price . into ( ) , "gas_price mismatch" ) ;
76- fail_unless ( t. nonce == tx. nonce . into ( ) , "nonce mismatch" ) ;
77- fail_unless ( t. value == tx. value . into ( ) , "value mismatch" ) ;
78- let to: Option < ethjson:: hash:: Address > = tx. to . into ( ) ;
79- let to: Option < Address > = to. map ( Into :: into) ;
80- match t. action {
81- Action :: Call ( dest) => fail_unless ( Some ( dest) == to, "call/destination mismatch" ) ,
82- Action :: Create => fail_unless ( None == to, "create mismatch" ) ,
58+
59+ let rlp: Vec < u8 > = test. rlp . clone ( ) . into ( ) ;
60+ let res = Rlp :: new ( & rlp)
61+ . as_val ( )
62+ . map_err ( :: error:: Error :: from)
63+ . and_then ( |t : UnverifiedTransaction | {
64+ let mut header: Header = Default :: default ( ) ;
65+ // Use high enough number to activate all required features.
66+ header. set_number ( BLOCK_NUMBER ) ;
67+
68+ let minimal = t. gas_required ( & spec. engine . schedule ( header. number ( ) ) ) . into ( ) ;
69+ if t. gas < minimal {
70+ return Err ( :: transaction:: Error :: InsufficientGas {
71+ minimal, got : t. gas ,
72+ } . into ( ) ) ;
73+ }
74+ spec. engine . verify_transaction_basic ( & t, & header) ?;
75+ Ok ( spec. engine . verify_transaction_unordered ( t, & header) ?)
76+ } ) ;
77+
78+ match ( res, result. hash , result. sender ) {
79+ ( Ok ( t) , Some ( hash) , Some ( sender) ) => {
80+ fail_unless ( t. sender ( ) == sender. into ( ) , "sender mismatch" ) ;
81+ fail_unless ( t. hash ( ) == hash. into ( ) , "hash mismatch" ) ;
82+ } ,
83+ ( Err ( _) , None , None ) => { } ,
84+ data => {
85+ fail_unless (
86+ false ,
87+ & format ! ( "Validity different: {:?}" , data)
88+ ) ;
89+ }
8390 }
8491 }
8592
@@ -92,13 +99,14 @@ fn do_json_test<H: FnMut(&str, HookType)>(json_data: &[u8], start_stop_hook: &mu
9299 failed
93100}
94101
95- declare_test ! { TransactionTests_ttEip155VitaliksHomesead , "TransactionTests/ttEip155VitaliksHomesead" }
96- declare_test ! { TransactionTests_ttEip155VitaliksEip158 , "TransactionTests/ttEip155VitaliksEip158" }
97- declare_test ! { TransactionTests_ttEip158 , "TransactionTests/ttEip158" }
98- declare_test ! { TransactionTests_ttFrontier , "TransactionTests/ttFrontier" }
99- declare_test ! { TransactionTests_ttHomestead , "TransactionTests/ttHomestead" }
100- declare_test ! { TransactionTests_ttVRuleEip158 , "TransactionTests/ttVRuleEip158" }
101- declare_test ! { TransactionTests_ttWrongRLPFrontier , "TransactionTests/ttWrongRLPFrontier" }
102- declare_test ! { TransactionTests_ttWrongRLPHomestead , "TransactionTests/ttWrongRLPHomestead" }
103- declare_test ! { TransactionTests_ttConstantinople , "TransactionTests/ttConstantinople" }
104- declare_test ! { TransactionTests_ttSpecConstantinople , "TransactionTests/ttSpecConstantinople" }
102+ declare_test ! { TransactionTests_ttAddress , "TransactionTests/ttAddress" }
103+ declare_test ! { TransactionTests_ttData , "TransactionTests/ttData" }
104+ declare_test ! { TransactionTests_ttGasLimit , "TransactionTests/ttGasLimit" }
105+ declare_test ! { TransactionTests_ttGasPrice , "TransactionTests/ttGasPrice" }
106+ declare_test ! { TransactionTests_ttNonce , "TransactionTests/ttNonce" }
107+ declare_test ! { TransactionTests_ttRSValue , "TransactionTests/ttRSValue" }
108+ declare_test ! { TransactionTests_ttSignature , "TransactionTests/ttSignature" }
109+ declare_test ! { TransactionTests_ttValue , "TransactionTests/ttValue" }
110+ declare_test ! { TransactionTests_ttVValue , "TransactionTests/ttVValue" }
111+ declare_test ! { TransactionTests_ttWrongRLP , "TransactionTests/ttWrongRLP" }
112+
0 commit comments