@@ -4,12 +4,12 @@ use std::convert::{TryFrom, TryInto};
4
4
use anyhow:: { anyhow, Context } ;
5
5
use cid:: Cid ;
6
6
use fvm3:: executor:: ApplyKind as ApplyKind3 ;
7
- use fvm3:: gas:: { Gas , GasCharge } ;
7
+ use fvm3:: gas:: GasCharge ;
8
8
use fvm3:: trace:: ExecutionEvent ;
9
+ use fvm3_ipld_encoding:: ipld_block:: IpldBlock ;
9
10
use fvm3_ipld_encoding:: tuple:: { Deserialize_tuple , Serialize_tuple } ;
10
11
use fvm3_ipld_encoding:: { to_vec, CborStore , RawBytes } ;
11
12
use fvm3_shared:: address:: Address ;
12
- use num_traits:: Zero ;
13
13
14
14
use fvm3_shared:: error:: { ErrorNumber , ExitCode } ;
15
15
use fvm3_shared:: receipt:: Receipt ;
@@ -205,24 +205,38 @@ fn fvm_machine_execute_message(
205
205
206
206
let exec_trace = if !apply_ret. exec_trace . is_empty ( ) {
207
207
let mut trace_iter = apply_ret. exec_trace . into_iter ( ) ;
208
- let initial_gas_charges: Vec < GasCharge > = trace_iter
209
- . clone ( )
210
- . take_while ( |e| matches ! ( e, & ExecutionEvent :: GasCharge ( _) ) )
211
- . map ( |e| match e {
212
- ExecutionEvent :: GasCharge ( gc) => gc,
213
- _ => GasCharge :: new ( "none" , Gas :: zero ( ) , Gas :: zero ( ) ) ,
214
- } )
215
- . collect ( ) ;
216
- match trace_iter. nth ( initial_gas_charges. len ( ) ) {
217
- Some ( c) => build_lotus_trace ( initial_gas_charges, c, & mut trace_iter)
218
- . ok ( )
219
- . and_then ( |t| to_vec ( & t) . ok ( ) )
220
- . map ( |trace| trace. into_boxed_slice ( ) . into ( ) ) ,
221
- _ => None ,
208
+ let mut initial_gas_charges = Vec :: new ( ) ;
209
+ loop {
210
+ match trace_iter. next ( ) {
211
+ Some ( gc @ ExecutionEvent :: GasCharge ( _) ) => initial_gas_charges. push ( gc) ,
212
+ Some ( ExecutionEvent :: Call {
213
+ from,
214
+ to,
215
+ method,
216
+ params,
217
+ value,
218
+ } ) => {
219
+ break build_lotus_trace (
220
+ from,
221
+ to,
222
+ method,
223
+ params,
224
+ value,
225
+ & mut initial_gas_charges. into_iter ( ) . chain ( & mut trace_iter) ,
226
+ )
227
+ . ok ( )
228
+ }
229
+ // Skip anything unexpected.
230
+ Some ( _) => { }
231
+ // Return none if we don't even have a call.
232
+ None => break None ,
233
+ }
222
234
}
223
235
} else {
224
236
None
225
- } ;
237
+ }
238
+ . and_then ( |t| to_vec ( & t) . ok ( ) )
239
+ . map ( |trace| trace. into_boxed_slice ( ) . into ( ) ) ;
226
240
227
241
let failure_info = apply_ret
228
242
. failure_info
@@ -343,66 +357,48 @@ pub struct LotusReceipt {
343
357
}
344
358
345
359
fn build_lotus_trace (
346
- initial_gas_charges : Vec < GasCharge > ,
347
- new_call : ExecutionEvent ,
360
+ from : u64 ,
361
+ to : Address ,
362
+ method : u64 ,
363
+ params : Option < IpldBlock > ,
364
+ value : TokenAmount ,
348
365
trace_iter : & mut impl Iterator < Item = ExecutionEvent > ,
349
366
) -> anyhow:: Result < LotusTrace > {
350
367
let mut new_trace = LotusTrace {
351
- msg : match new_call {
352
- ExecutionEvent :: Call {
353
- from,
354
- to,
355
- method,
356
- params,
357
- value,
358
- } => Message {
359
- version : 0 ,
360
- from : Address :: new_id ( from) ,
361
- to,
362
- value,
363
- sequence : 0 ,
364
- method_num : method,
365
- params : params. map ( |b| b. data ) . unwrap_or_default ( ) . into ( ) ,
366
- gas_limit : 0 ,
367
- gas_fee_cap : TokenAmount :: default ( ) ,
368
- gas_premium : TokenAmount :: default ( ) ,
369
- } ,
370
- _ => {
371
- return Err ( anyhow ! ( "expected ExecutionEvent of type Call" ) ) ;
372
- }
368
+ msg : Message {
369
+ version : 0 ,
370
+ from : Address :: new_id ( from) ,
371
+ to,
372
+ value,
373
+ sequence : 0 ,
374
+ method_num : method,
375
+ params : params. map ( |b| b. data ) . unwrap_or_default ( ) . into ( ) ,
376
+ gas_limit : 0 ,
377
+ gas_fee_cap : TokenAmount :: default ( ) ,
378
+ gas_premium : TokenAmount :: default ( ) ,
373
379
} ,
374
380
msg_receipt : LotusReceipt {
375
381
exit_code : ExitCode :: OK ,
376
382
return_data : RawBytes :: default ( ) ,
377
383
gas_used : 0 ,
378
384
} ,
379
385
error : String :: new ( ) ,
380
- gas_charges : initial_gas_charges
381
- . iter ( )
382
- . cloned ( )
383
- . map (
384
- |GasCharge {
385
- name,
386
- compute_gas,
387
- other_gas,
388
- elapsed : _, // TODO: thread timing through to lotus.
389
- } | LotusGasCharge {
390
- name,
391
- total_gas : ( compute_gas + other_gas) . round_up ( ) ,
392
- compute_gas : compute_gas. round_up ( ) ,
393
- other_gas : other_gas. round_up ( ) ,
394
- } ,
395
- )
396
- . collect ( ) ,
386
+ gas_charges : vec ! [ ] ,
397
387
subcalls : vec ! [ ] ,
398
388
} ;
399
389
400
390
while let Some ( trace) = trace_iter. next ( ) {
401
391
match trace {
402
- ExecutionEvent :: Call { .. } => {
403
- new_trace
404
- . subcalls
405
- . push ( build_lotus_trace ( vec ! [ ] , trace, trace_iter) ?) ;
392
+ ExecutionEvent :: Call {
393
+ from,
394
+ to,
395
+ method,
396
+ params,
397
+ value,
398
+ } => {
399
+ new_trace. subcalls . push ( build_lotus_trace (
400
+ from, to, method, params, value, trace_iter,
401
+ ) ?) ;
406
402
}
407
403
ExecutionEvent :: CallReturn ( exit_code, return_data) => {
408
404
new_trace. msg_receipt = LotusReceipt {
@@ -472,8 +468,9 @@ mod test {
472
468
} ;
473
469
let return_result =
474
470
ExecutionEvent :: CallError ( SyscallError :: new ( IllegalArgument , "illegal" ) ) ;
471
+ let initial_gas_charge = GasCharge :: new ( "gas_test" , Gas :: new ( 1 ) , Gas :: new ( 2 ) ) ;
475
472
let trace = vec ! [
476
- call_event . clone( ) ,
473
+ ExecutionEvent :: GasCharge ( initial_gas_charge . clone( ) ) ,
477
474
call_event. clone( ) ,
478
475
return_result. clone( ) ,
479
476
call_event. clone( ) ,
@@ -485,10 +482,12 @@ mod test {
485
482
486
483
let mut trace_iter = trace. into_iter ( ) ;
487
484
488
- let initial_gas_charge = GasCharge :: new ( "gas_test" , Gas :: new ( 1 ) , Gas :: new ( 2 ) ) ;
489
485
let lotus_trace = build_lotus_trace (
490
- vec ! [ initial_gas_charge. clone( ) ] ,
491
- trace_iter. next ( ) . unwrap ( ) ,
486
+ 0 ,
487
+ Address :: new_id ( 0 ) ,
488
+ 0 ,
489
+ None ,
490
+ TokenAmount :: default ( ) ,
492
491
& mut trace_iter,
493
492
)
494
493
. unwrap ( ) ;
0 commit comments