Skip to content

Commit 3674f77

Browse files
authored
[static-ptbs] Add PTB tracing support (#24446)
## Description Adds support for tracing into the static PTB adapter runtime. The `trace_utils` are somewhat changed in order to handle the new value types. I tried to be as minimally invasive to the existing adapter runtime. Although I did need to add two small access functions in order to get to the underlying VM value for tracing. ## Test plan Ran some local replays of transactions and inspected the trace output (esp. around `ExternalEvent`s). --- ## Release notes Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required. For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates. - [ ] Protocol: - [ ] Nodes (Validators and Full nodes): - [ ] gRPC: - [ ] JSON-RPC: - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK: - [ ] Indexing Framework:
1 parent 4edc6e7 commit 3674f77

File tree

5 files changed

+534
-21
lines changed

5 files changed

+534
-21
lines changed

sui-execution/latest/sui-adapter/src/static_programmable_transactions/execution/context.rs

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ use crate::{
1111
sp,
1212
static_programmable_transactions::{
1313
env::Env,
14-
execution::values::{Local, Locals, Value},
14+
execution::{
15+
trace_utils,
16+
values::{Local, Locals, Value},
17+
},
1518
linkage::resolved_linkage::{ResolvedLinkage, RootedLinkage},
1619
loading::ast::{Datatype, ObjectMutability},
1720
typing::ast::{self as T, Type},
@@ -663,7 +666,7 @@ impl<'env, 'pc, 'vm, 'state, 'linkage, 'gas> Context<'env, 'pc, 'vm, 'state, 'li
663666
&mut self,
664667
function: T::LoadedFunction,
665668
args: Vec<CtxValue>,
666-
trace_builder_opt: Option<&mut MoveTraceBuilder>,
669+
trace_builder_opt: &mut Option<MoveTraceBuilder>,
667670
) -> Result<Vec<CtxValue>, ExecutionError> {
668671
let result = self.execute_function_bypass_visibility(
669672
&function.runtime_id,
@@ -689,7 +692,7 @@ impl<'env, 'pc, 'vm, 'state, 'linkage, 'gas> Context<'env, 'pc, 'vm, 'state, 'li
689692
ty_args: &[Type],
690693
args: Vec<CtxValue>,
691694
linkage: &RootedLinkage,
692-
tracer: Option<&mut MoveTraceBuilder>,
695+
tracer: &mut Option<MoveTraceBuilder>,
693696
) -> Result<Vec<CtxValue>, ExecutionError> {
694697
let ty_args = ty_args
695698
.iter()
@@ -710,7 +713,7 @@ impl<'env, 'pc, 'vm, 'state, 'linkage, 'gas> Context<'env, 'pc, 'vm, 'state, 'li
710713
&mut data_store,
711714
&mut SuiGasMeter(gas_status),
712715
&mut self.native_extensions,
713-
tracer,
716+
tracer.as_mut(),
714717
)
715718
.map_err(|e| self.env.convert_linked_vm_error(e, linkage))?;
716719
Ok(values.into_iter().map(|v| CtxValue(v.into())).collect())
@@ -867,7 +870,7 @@ impl<'env, 'pc, 'vm, 'state, 'linkage, 'gas> Context<'env, 'pc, 'vm, 'state, 'li
867870
package_id: ObjectID,
868871
modules: &[CompiledModule],
869872
linkage: &RootedLinkage,
870-
mut trace_builder_opt: Option<&mut MoveTraceBuilder>,
873+
trace_builder_opt: &mut Option<MoveTraceBuilder>,
871874
) -> Result<(), ExecutionError> {
872875
for module in modules {
873876
let Some((fdef_idx, fdef)) = module.find_function_def_by_name(INIT_FN_NAME.as_str())
@@ -895,14 +898,16 @@ impl<'env, 'pc, 'vm, 'state, 'linkage, 'gas> Context<'env, 'pc, 'vm, 'state, 'li
895898
vec![CtxValue(tx_context)]
896899
};
897900
debug_assert_eq!(self.gas_charger.move_gas_status().stack_height_current(), 0);
901+
trace_utils::trace_move_call_start(trace_builder_opt);
898902
let return_values = self.execute_function_bypass_visibility(
899903
&module.self_id(),
900904
INIT_FN_NAME,
901905
&[],
902906
args,
903907
linkage,
904-
trace_builder_opt.as_deref_mut(),
908+
trace_builder_opt,
905909
)?;
910+
trace_utils::trace_move_call_end(trace_builder_opt);
906911

907912
let storage_id = ModuleId::new(package_id.into(), module.self_id().name().to_owned());
908913
self.take_user_events(
@@ -926,7 +931,7 @@ impl<'env, 'pc, 'vm, 'state, 'linkage, 'gas> Context<'env, 'pc, 'vm, 'state, 'li
926931
mut modules: Vec<CompiledModule>,
927932
dep_ids: &[ObjectID],
928933
linkage: ResolvedLinkage,
929-
trace_builder_opt: Option<&mut MoveTraceBuilder>,
934+
trace_builder_opt: &mut Option<MoveTraceBuilder>,
930935
) -> Result<ObjectID, ExecutionError> {
931936
let runtime_id = if <Mode>::packages_are_predefined() {
932937
// do not calculate or substitute id for predefined packages
@@ -1242,6 +1247,11 @@ impl CtxValue {
12421247
pub fn into_upgrade_ticket(self) -> Result<UpgradeTicket, ExecutionError> {
12431248
self.0.into_upgrade_ticket()
12441249
}
1250+
1251+
/// Used to get access the inner Value for tracing.
1252+
pub(super) fn inner_for_tracing(&self) -> &Value {
1253+
&self.0
1254+
}
12451255
}
12461256

12471257
fn load_object_arg(

sui-execution/latest/sui-adapter/src/static_programmable_transactions/execution/interpreter.rs

Lines changed: 67 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use crate::{
88
static_programmable_transactions::{
99
env::Env,
1010
execution::context::{Context, CtxValue},
11+
execution::trace_utils,
1112
typing::ast as T,
1213
},
1314
};
@@ -50,7 +51,10 @@ where
5051

5152
match result {
5253
Ok(result) => Ok((result, timings)),
53-
Err(e) => Err((e, timings)),
54+
Err(e) => {
55+
trace_utils::trace_execution_error(trace_builder_opt, e.to_string());
56+
Err((e, timings))
57+
}
5458
}
5559
}
5660

@@ -86,15 +90,15 @@ where
8690
pure,
8791
receiving,
8892
)?;
93+
94+
trace_utils::trace_ptb_summary(&mut context, trace_builder_opt, &commands)?;
95+
8996
let mut mode_results = Mode::empty_results();
9097
for sp!(idx, c) in commands {
9198
let start = Instant::now();
92-
if let Err(err) = execute_command::<Mode>(
93-
&mut context,
94-
&mut mode_results,
95-
c,
96-
trace_builder_opt.as_mut(),
97-
) {
99+
if let Err(err) =
100+
execute_command::<Mode>(&mut context, &mut mode_results, c, trace_builder_opt)
101+
{
98102
let object_runtime = context.object_runtime()?;
99103
// We still need to record the loaded child objects for replay
100104
let loaded_runtime_objects = object_runtime.loaded_runtime_objects();
@@ -140,7 +144,7 @@ fn execute_command<Mode: ExecutionMode>(
140144
context: &mut Context,
141145
mode_results: &mut Mode::ExecutionResults,
142146
c: T::Command_,
143-
trace_builder_opt: Option<&mut MoveTraceBuilder>,
147+
trace_builder_opt: &mut Option<MoveTraceBuilder>,
144148
) -> Result<(), ExecutionError> {
145149
let T::Command_ {
146150
command,
@@ -157,6 +161,7 @@ fn execute_command<Mode: ExecutionMode>(
157161
let mut args_to_update = vec![];
158162
let result = match command {
159163
T::Command__::MoveCall(move_call) => {
164+
trace_utils::trace_move_call_start(trace_builder_opt);
160165
let T::MoveCall {
161166
function,
162167
arguments,
@@ -170,7 +175,9 @@ fn execute_command<Mode: ExecutionMode>(
170175
)
171176
}
172177
let arguments = context.arguments(arguments)?;
173-
context.vm_move_call(function, arguments, trace_builder_opt)?
178+
let res = context.vm_move_call(function, arguments, trace_builder_opt);
179+
trace_utils::trace_move_call_end(trace_builder_opt);
180+
res?
174181
}
175182
T::Command__::TransferObjects(objects, recipient) => {
176183
let object_tys = objects
@@ -183,14 +190,16 @@ fn execute_command<Mode: ExecutionMode>(
183190
object_values.len() == object_tys.len(),
184191
"object values and types mismatch"
185192
);
193+
trace_utils::trace_transfer(context, trace_builder_opt, &object_values, &object_tys)?;
186194
for (object_value, ty) in object_values.into_iter().zip(object_tys) {
187195
// TODO should we just call a Move function?
188196
let recipient = Owner::AddressOwner(recipient.into());
189197
context.transfer_object(recipient, ty, object_value)?;
190198
}
191199
vec![]
192200
}
193-
T::Command__::SplitCoins(_, coin, amounts) => {
201+
T::Command__::SplitCoins(ty, coin, amounts) => {
202+
let mut trace_values = vec![];
194203
// TODO should we just call a Move function?
195204
if Mode::TRACK_EXECUTION {
196205
args_to_update.push(coin.clone());
@@ -206,6 +215,13 @@ fn execute_command<Mode: ExecutionMode>(
206215
};
207216
total = new_total;
208217
}
218+
trace_utils::add_move_value_info_from_ctx_value(
219+
context,
220+
trace_builder_opt,
221+
&mut trace_values,
222+
&ty,
223+
&coin_ref,
224+
)?;
209225
let coin_value = context.copy_value(&coin_ref)?.coin_ref_value()?;
210226
fp_ensure!(
211227
coin_value >= total,
@@ -215,21 +231,48 @@ fn execute_command<Mode: ExecutionMode>(
215231
)
216232
);
217233
coin_ref.coin_ref_subtract_balance(total)?;
218-
amount_values
234+
let amounts = amount_values
219235
.into_iter()
220236
.map(|a| context.new_coin(a))
221-
.collect::<Result<_, _>>()?
237+
.collect::<Result<Vec<_>, _>>()?;
238+
trace_utils::trace_split_coins(
239+
context,
240+
trace_builder_opt,
241+
&ty,
242+
trace_values,
243+
&amounts,
244+
total,
245+
)?;
246+
247+
amounts
222248
}
223-
T::Command__::MergeCoins(_, target, coins) => {
249+
T::Command__::MergeCoins(ty, target, coins) => {
250+
let mut trace_values = vec![];
224251
// TODO should we just call a Move function?
225252
if Mode::TRACK_EXECUTION {
226253
args_to_update.push(target.clone());
227254
}
228255
let target_ref: CtxValue = context.argument(target)?;
256+
trace_utils::add_move_value_info_from_ctx_value(
257+
context,
258+
trace_builder_opt,
259+
&mut trace_values,
260+
&ty,
261+
&target_ref,
262+
)?;
229263
let coins = context.arguments(coins)?;
230264
let amounts = coins
231265
.into_iter()
232-
.map(|coin| context.destroy_coin(coin))
266+
.map(|coin| {
267+
trace_utils::add_move_value_info_from_ctx_value(
268+
context,
269+
trace_builder_opt,
270+
&mut trace_values,
271+
&ty,
272+
&coin,
273+
)?;
274+
context.destroy_coin(coin)
275+
})
233276
.collect::<Result<Vec<_>, _>>()?;
234277
let mut additional: u64 = 0;
235278
for amount in amounts {
@@ -246,13 +289,22 @@ fn execute_command<Mode: ExecutionMode>(
246289
ExecutionError::from_kind(ExecutionErrorKind::CoinBalanceOverflow,)
247290
);
248291
target_ref.coin_ref_add_balance(additional)?;
292+
trace_utils::trace_merge_coins(
293+
context,
294+
trace_builder_opt,
295+
&ty,
296+
trace_values,
297+
additional,
298+
)?;
249299
vec![]
250300
}
251301
T::Command__::MakeMoveVec(ty, items) => {
252302
let items: Vec<CtxValue> = context.arguments(items)?;
303+
trace_utils::trace_make_move_vec(context, trace_builder_opt, &items, &ty)?;
253304
vec![CtxValue::vec_pack(ty, items)?]
254305
}
255306
T::Command__::Publish(module_bytes, dep_ids, linkage) => {
307+
trace_utils::trace_publish_event(trace_builder_opt)?;
256308
let modules =
257309
context.deserialize_modules(&module_bytes, /* is upgrade */ false)?;
258310

@@ -277,6 +329,7 @@ fn execute_command<Mode: ExecutionMode>(
277329
upgrade_ticket,
278330
linkage,
279331
) => {
332+
trace_utils::trace_upgrade_event(trace_builder_opt)?;
280333
let upgrade_ticket = context
281334
.argument::<CtxValue>(upgrade_ticket)?
282335
.into_upgrade_ticket()?;

sui-execution/latest/sui-adapter/src/static_programmable_transactions/execution/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@
33

44
pub mod context;
55
pub mod interpreter;
6+
mod trace_utils;
67
pub mod values;

0 commit comments

Comments
 (0)