11use crate :: types:: Spec ;
2- use aurora_evm:: backend:: MemoryAccount ;
3- use primitive_types:: { H160 , H256 } ;
2+ use aurora_evm:: backend:: { Apply , Basic , MemoryAccount } ;
3+ use aurora_evm:: executor:: stack:: Authorization ;
4+ use primitive_types:: { H160 , H256 , U256 } ;
5+ use serde:: { Deserialize , Serialize } ;
46use std:: collections:: BTreeMap ;
7+ use std:: time:: Duration ;
58
69#[ derive( Clone , Debug ) ]
710pub struct FailedTestDetails {
@@ -18,6 +21,106 @@ pub struct TestExecutionResult {
1821 pub total : u64 ,
1922 pub failed : u64 ,
2023 pub failed_tests : Vec < FailedTestDetails > ,
24+ pub bench : Vec < TestBench > ,
25+ pub dump_successful_txs : Vec < RawInput > ,
26+ }
27+
28+ #[ derive( Clone , Debug , Serialize , Deserialize ) ]
29+ pub struct RawInput {
30+ pub spec : RawSpec ,
31+ pub caller : H160 ,
32+ pub value : U256 ,
33+ pub data : Vec < u8 > ,
34+ pub gas_limit : u64 ,
35+ pub access_list : Vec < ( H160 , Vec < H256 > ) > ,
36+ pub authorization_list : Vec < Authorization > ,
37+ pub apply_values : Vec < RawApply > ,
38+ }
39+
40+ #[ derive( Clone , Debug , Serialize , Deserialize ) ]
41+ pub enum RawApply {
42+ Modify {
43+ address : H160 ,
44+ basic : Basic ,
45+ code : Option < Vec < u8 > > ,
46+ storage : Vec < ( H256 , H256 ) > ,
47+ reset_storage : bool ,
48+ } ,
49+ Delete {
50+ address : H160 ,
51+ } ,
52+ }
53+
54+ impl < I > From < Apply < I > > for RawApply
55+ where
56+ I : IntoIterator < Item = ( H256 , H256 ) > ,
57+ {
58+ fn from ( value : Apply < I > ) -> Self {
59+ match value {
60+ Apply :: Modify {
61+ address,
62+ basic,
63+ code,
64+ storage,
65+ reset_storage,
66+ } => Self :: Modify {
67+ address,
68+ basic,
69+ code,
70+ storage : storage. into_iter ( ) . collect ( ) ,
71+ reset_storage,
72+ } ,
73+ Apply :: Delete { address } => Self :: Delete { address } ,
74+ }
75+ }
76+ }
77+
78+ #[ derive( Clone , Debug , Serialize , Deserialize ) ]
79+ pub enum RawSpec {
80+ Frontier ,
81+ Homestead ,
82+ TangerineWhistle ,
83+ SpuriousDragon ,
84+ Byzantium ,
85+ Constantinople ,
86+ Petersburg ,
87+ Istanbul ,
88+ Berlin ,
89+ London ,
90+ Merge ,
91+ Shanghai ,
92+ Cancun ,
93+ Prague ,
94+ Osaka ,
95+ }
96+
97+ impl From < Spec > for RawSpec {
98+ fn from ( spec : Spec ) -> Self {
99+ match spec {
100+ Spec :: Frontier => Self :: Frontier ,
101+ Spec :: Homestead => Self :: Homestead ,
102+ Spec :: Tangerine => Self :: TangerineWhistle ,
103+ Spec :: SpuriousDragon => Self :: SpuriousDragon ,
104+ Spec :: Byzantium => Self :: Byzantium ,
105+ Spec :: Constantinople => Self :: Constantinople ,
106+ Spec :: Petersburg => Self :: Petersburg ,
107+ Spec :: Istanbul => Self :: Istanbul ,
108+ Spec :: Berlin => Self :: Berlin ,
109+ Spec :: London => Self :: London ,
110+ Spec :: Merge => Self :: Merge ,
111+ Spec :: Shanghai => Self :: Shanghai ,
112+ Spec :: Cancun => Self :: Cancun ,
113+ Spec :: Prague => Self :: Prague ,
114+ Spec :: Osaka => Self :: Osaka ,
115+ }
116+ }
117+ }
118+
119+ #[ derive( Clone , Debug ) ]
120+ pub struct TestBench {
121+ pub name : String ,
122+ pub spec : Spec ,
123+ pub elapsed : Duration ,
21124}
22125
23126impl TestExecutionResult {
@@ -28,12 +131,89 @@ impl TestExecutionResult {
28131 total : 0 ,
29132 failed : 0 ,
30133 failed_tests : Vec :: new ( ) ,
134+ bench : Vec :: new ( ) ,
135+ dump_successful_txs : Vec :: new ( ) ,
31136 }
32137 }
33138
34139 pub fn merge ( & mut self , src : Self ) {
35140 self . failed_tests . extend ( src. failed_tests ) ;
36141 self . total += src. total ;
37142 self . failed += src. failed ;
143+
144+ for bench in src. bench {
145+ self . set_benchmark ( bench) ;
146+ }
147+
148+ self . dump_successful_txs . extend ( src. dump_successful_txs ) ;
149+ }
150+
151+ pub fn set_benchmark ( & mut self , bench : TestBench ) {
152+ if self . bench . is_empty ( ) {
153+ self . bench . push ( bench) ;
154+ return ;
155+ }
156+
157+ if self . bench . len ( ) < 100 {
158+ self . bench . push ( bench) ;
159+ return ;
160+ }
161+
162+ // If has smaller elapsed than all existing then skip
163+ if !self . bench . iter ( ) . any ( |b| bench. elapsed > b. elapsed ) {
164+ return ;
165+ }
166+
167+ let mut min_idx = 0usize ;
168+ let mut min_elapsed = self . bench [ 0 ] . elapsed ;
169+ for ( i, b) in self . bench . iter ( ) . enumerate ( ) . skip ( 1 ) {
170+ if b. elapsed < min_elapsed {
171+ min_elapsed = b. elapsed ;
172+ min_idx = i;
173+ }
174+ }
175+
176+ if bench. elapsed > min_elapsed {
177+ self . bench [ min_idx] = bench;
178+ }
179+ }
180+
181+ pub fn print_bench ( & self ) {
182+ let mut items = self . bench . clone ( ) ;
183+ items. sort_unstable_by ( |a, b| b. elapsed . cmp ( & a. elapsed ) ) ;
184+
185+ if items. is_empty ( ) {
186+ return ;
187+ }
188+
189+ let formatted: Vec < ( String , String , String ) > = items
190+ . iter ( )
191+ . map ( |b| {
192+ let elapsed_str = format ! ( "{:.6}s" , b. elapsed. as_secs_f64( ) ) ;
193+ let spec_str = format ! ( "{:?}" , b. spec) ;
194+ let name_str = b. name . clone ( ) ;
195+ ( elapsed_str, spec_str, name_str)
196+ } )
197+ . collect ( ) ;
198+
199+ let mut w_elapsed = 0usize ;
200+ let mut w_spec = 0usize ;
201+ let mut w_name = 0usize ;
202+ for ( e, s, n) in & formatted {
203+ w_elapsed = w_elapsed. max ( e. len ( ) ) ;
204+ w_spec = w_spec. max ( s. len ( ) ) ;
205+ w_name = w_name. max ( n. len ( ) ) ;
206+ }
207+
208+ let bold_on = "\x1b [1m" ;
209+ let gray_on = "\x1b [90m" ;
210+ let reset = "\x1b [0m" ;
211+
212+ for ( e, s, n) in formatted {
213+ let e_pad = format ! ( "{e:w_elapsed$}" ) ;
214+ let s_pad = format ! ( "{s:w_spec$}" ) ;
215+ let n_pad = format ! ( "{n:w_name$}" ) ;
216+ println ! ( "{bold_on}{e_pad}{reset} {gray_on}{s_pad}{reset} {n_pad}" , ) ;
217+ }
38218 }
39219}
0 commit comments