@@ -73,6 +73,16 @@ pub enum Action {
7373 /* TODO: Support Reward */
7474}
7575
76+ impl Action {
77+ pub fn gas ( & self ) -> Option < U256 > {
78+ match self {
79+ Action :: Call ( ref call) => Some ( call. gas ) ,
80+ Action :: Create ( ref create) => Some ( create. gas ) ,
81+ Action :: SelfDestruct ( _) => None ,
82+ }
83+ }
84+ }
85+
7686impl TryFrom < VmAction > for Action {
7787 type Error = String ;
7888
@@ -136,10 +146,6 @@ pub enum ActionResult {
136146 Call ( CallResult ) ,
137147 /// Create
138148 Create ( CreateResult ) ,
139- /// Call failure
140- FailedCall ( TraceError ) ,
141- /// Creation failure
142- FailedCreate ( TraceError ) ,
143149 /// None
144150 None ,
145151}
@@ -151,6 +157,8 @@ pub struct LocalizedTrace {
151157 pub action : Action ,
152158 /// Result
153159 pub result : ActionResult ,
160+ /// The error message if the transaction failed.
161+ pub error : Option < String > ,
154162 /// Trace address
155163 pub trace_address : Vec < usize > ,
156164 /// Subtraces
@@ -193,17 +201,15 @@ impl Serialize for LocalizedTrace {
193201 ActionResult :: Create ( ref create) => {
194202 struc. serialize_field ( "result" , create) ?
195203 }
196- ActionResult :: FailedCall ( ref error) => {
197- struc. serialize_field ( "error" , & error. to_string ( ) ) ?
198- }
199- ActionResult :: FailedCreate ( ref error) => {
200- struc. serialize_field ( "error" , & error. to_string ( ) ) ?
201- }
202204 ActionResult :: None => {
203205 struc. serialize_field ( "result" , & None as & Option < u8 > ) ?
204206 }
205207 }
206208
209+ if let Some ( error) = & self . error {
210+ struc. serialize_field ( "error" , error) ?;
211+ }
212+
207213 struc. serialize_field ( "traceAddress" , & self . trace_address ) ?;
208214 struc. serialize_field ( "subtraces" , & self . subtraces ) ?;
209215 struc. serialize_field (
@@ -238,48 +244,50 @@ impl LocalizedTrace {
238244 if !matches ! ( self . action, Action :: Call ( _) ) {
239245 bail ! ( JsonRpcError :: internal_error( ) ) ;
240246 }
247+ let gas =
248+ self . action . gas ( ) . expect ( "call action should have gas" ) ;
249+ let gas_used = gas - call_result. gas_left ;
250+ self . result = ActionResult :: Call ( CallResult {
251+ gas_used,
252+ output : call_result. return_data . clone ( ) . into ( ) ,
253+ } ) ;
241254 match call_result. outcome {
242- Outcome :: Success => {
243- // FIXME(lpl): Convert gas_left to gas_used.
244- self . result = ActionResult :: Call ( CallResult {
245- gas_used : call_result. gas_left ,
246- output : call_result. return_data . into ( ) ,
247- } )
248- }
249255 Outcome :: Reverted => {
250- self . result =
251- ActionResult :: FailedCall ( TraceError :: Reverted ) ;
256+ self . error = Some ( TraceError :: Reverted . to_string ( ) ) ;
252257 }
253258 Outcome :: Fail => {
254- self . result = ActionResult :: FailedCall (
255- TraceError :: Error ( call_result. return_data . into ( ) ) ,
259+ self . error = Some (
260+ TraceError :: Error ( call_result. return_data . into ( ) )
261+ . to_string ( ) ,
256262 ) ;
257263 }
264+ _ => { }
258265 }
259266 }
260267 VmAction :: CreateResult ( create_result) => {
261268 if !matches ! ( self . action, Action :: Create ( _) ) {
262269 bail ! ( JsonRpcError :: internal_error( ) ) ;
263270 }
271+ // FIXME(lpl): Check if `return_data` is `code`.
272+ let gas =
273+ self . action . gas ( ) . expect ( "call action should have gas" ) ;
274+ let gas_used = gas - create_result. gas_left ;
275+ self . result = ActionResult :: Create ( CreateResult {
276+ gas_used,
277+ code : create_result. return_data . clone ( ) . into ( ) ,
278+ address : create_result. addr ,
279+ } ) ;
264280 match create_result. outcome {
265- Outcome :: Success => {
266- // FIXME(lpl): Convert gas_left to gas_used.
267- // FIXME(lpl): Check if `return_data` is `code`.
268- self . result = ActionResult :: Create ( CreateResult {
269- gas_used : create_result. gas_left ,
270- code : create_result. return_data . into ( ) ,
271- address : create_result. addr ,
272- } )
273- }
274281 Outcome :: Reverted => {
275- self . result =
276- ActionResult :: FailedCreate ( TraceError :: Reverted ) ;
282+ self . error = Some ( TraceError :: Reverted . to_string ( ) ) ;
277283 }
278284 Outcome :: Fail => {
279- self . result = ActionResult :: FailedCreate (
280- TraceError :: Error ( create_result. return_data . into ( ) ) ,
285+ self . error = Some (
286+ TraceError :: Error ( create_result. return_data . into ( ) )
287+ . to_string ( ) ,
281288 ) ;
282289 }
290+ _ => { }
283291 }
284292 }
285293 _ => bail ! ( JsonRpcError :: internal_error( ) ) ,
@@ -299,6 +307,8 @@ pub struct Trace {
299307 action : Action ,
300308 /// Result
301309 result : ActionResult ,
310+ /// Error
311+ error : Option < String > ,
302312}
303313
304314impl Serialize for Trace {
@@ -327,17 +337,15 @@ impl Serialize for Trace {
327337 ActionResult :: Create ( ref create) => {
328338 struc. serialize_field ( "result" , create) ?
329339 }
330- ActionResult :: FailedCall ( ref error) => {
331- struc. serialize_field ( "error" , & error. to_string ( ) ) ?
332- }
333- ActionResult :: FailedCreate ( ref error) => {
334- struc. serialize_field ( "error" , & error. to_string ( ) ) ?
335- }
336340 ActionResult :: None => {
337341 struc. serialize_field ( "result" , & None as & Option < u8 > ) ?
338342 }
339343 }
340344
345+ if let Some ( error) = & self . error {
346+ struc. serialize_field ( "error" , error) ?;
347+ }
348+
341349 struc. serialize_field ( "traceAddress" , & self . trace_address ) ?;
342350 struc. serialize_field ( "subtraces" , & self . subtraces ) ?;
343351
0 commit comments