@@ -11,10 +11,12 @@ use num_traits::Zero;
11
11
12
12
use super :: { Backtrace , CallManager , InvocationResult , NO_DATA_BLOCK_ID } ;
13
13
use crate :: call_manager:: backtrace:: Frame ;
14
+ use crate :: call_manager:: FinishRet ;
14
15
use crate :: gas:: GasTracker ;
15
16
use crate :: kernel:: { ClassifyResult , ExecutionError , Kernel , Result } ;
16
17
use crate :: machine:: Machine ;
17
18
use crate :: syscalls:: error:: Abort ;
19
+ use crate :: trace:: { ExecutionEvent , ExecutionTrace , SendParams } ;
18
20
use crate :: { account_actor, syscall_error} ;
19
21
20
22
/// The default [`CallManager`] implementation.
@@ -40,6 +42,8 @@ pub struct InnerDefaultCallManager<M> {
40
42
call_stack_depth : u32 ,
41
43
/// The current chain of errors, if any.
42
44
backtrace : Backtrace ,
45
+ /// The current execution trace.
46
+ exec_trace : ExecutionTrace ,
43
47
}
44
48
45
49
#[ doc( hidden) ]
73
77
num_actors_created : 0 ,
74
78
call_stack_depth : 0 ,
75
79
backtrace : Backtrace :: default ( ) ,
80
+ exec_trace : vec ! [ ] ,
76
81
} ) ) )
77
82
}
78
83
87
92
where
88
93
K : Kernel < CallManager = Self > ,
89
94
{
95
+ if self . machine . context ( ) . tracing {
96
+ self . exec_trace . push ( ExecutionEvent :: Call ( SendParams {
97
+ from,
98
+ to,
99
+ method,
100
+ params : params. clone ( ) ,
101
+ value : value. clone ( ) ,
102
+ } ) ) ;
103
+ }
104
+
90
105
// We check _then_ set because we don't count the top call. This effectivly allows a
91
106
// call-stack depth of `max_call_depth + 1` (or `max_call_depth` sub-calls). While this is
92
107
// likely a bug, this is how NV15 behaves so we mimic that behavior here.
@@ -108,6 +123,11 @@ where
108
123
self . call_stack_depth += 1 ;
109
124
let result = self . send_unchecked :: < K > ( from, to, method, params, value) ;
110
125
self . call_stack_depth -= 1 ;
126
+
127
+ if self . machine . context ( ) . tracing {
128
+ self . exec_trace . push ( ExecutionEvent :: Return ( result. clone ( ) ) ) ;
129
+ }
130
+
111
131
result
112
132
}
113
133
@@ -124,12 +144,19 @@ where
124
144
res
125
145
}
126
146
127
- fn finish ( mut self ) -> ( i64 , Backtrace , Self :: Machine ) {
147
+ fn finish ( mut self ) -> ( FinishRet , Self :: Machine ) {
128
148
let gas_used = self . gas_tracker . gas_used ( ) . max ( 0 ) ;
129
149
130
150
let inner = self . 0 . take ( ) . expect ( "call manager is poisoned" ) ;
131
151
// TODO: Having to check against zero here is fishy, but this is what lotus does.
132
- ( gas_used, inner. backtrace , inner. machine )
152
+ (
153
+ FinishRet {
154
+ gas_used,
155
+ backtrace : inner. backtrace ,
156
+ exec_trace : inner. exec_trace ,
157
+ } ,
158
+ inner. machine ,
159
+ )
133
160
}
134
161
135
162
// Accessor methods so the trait can implement some common methods by default.
0 commit comments