From 8e6542762efa3dbb45f2a4082e8e0b6c4c7a3113 Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Tue, 28 Feb 2023 13:09:45 -0800 Subject: [PATCH 1/2] feat: plumb codec through lotus trace This replaces the trace types with FVM specific ones. It: - Adds codecs to params/return values. - Removes unset fields like nonce, gas, etc. - Removes the error string field (error information is still included in the top-level error message. - Adds timing information to gas charges. --- rust/src/fvm/machine.rs | 79 ++++++++++++++++++++++++++--------------- 1 file changed, 51 insertions(+), 28 deletions(-) diff --git a/rust/src/fvm/machine.rs b/rust/src/fvm/machine.rs index 6b4d1e75..505e516f 100644 --- a/rust/src/fvm/machine.rs +++ b/rust/src/fvm/machine.rs @@ -8,8 +8,9 @@ use fvm3::gas::GasCharge; use fvm3::trace::ExecutionEvent; use fvm3_ipld_encoding::ipld_block::IpldBlock; use fvm3_ipld_encoding::tuple::{Deserialize_tuple, Serialize_tuple}; -use fvm3_ipld_encoding::{to_vec, CborStore, RawBytes}; +use fvm3_ipld_encoding::{strict_bytes, to_vec, CborStore}; use fvm3_shared::address::Address; +use fvm3_shared::MethodNum; use fvm3_shared::error::{ErrorNumber, ExitCode}; use fvm3_shared::receipt::Receipt; @@ -358,22 +359,34 @@ struct LotusGasCharge { pub total_gas: u64, pub compute_gas: u64, pub other_gas: u64, + pub duration_nanos: u64, } #[derive(Clone, Debug, Serialize_tuple, Deserialize_tuple)] -struct LotusTrace { - pub msg: Message, - pub msg_receipt: LotusReceipt, - pub error: String, +struct Trace { + pub msg: TraceMessage, + pub msg_ret: TraceReturn, pub gas_charges: Vec, - pub subcalls: Vec, + pub subcalls: Vec, } #[derive(Serialize_tuple, Deserialize_tuple, Debug, PartialEq, Eq, Clone)] -pub struct LotusReceipt { +pub struct TraceMessage { + pub from: Address, + pub to: Address, + pub value: TokenAmount, + pub method_num: MethodNum, + #[serde(with = "strict_bytes")] + pub params: Vec, + pub codec: u64, +} + +#[derive(Serialize_tuple, Deserialize_tuple, Debug, PartialEq, Eq, Clone)] +pub struct TraceReturn { pub exit_code: ExitCode, - pub return_data: RawBytes, - pub gas_used: i64, + #[serde(with = "strict_bytes")] + pub return_data: Vec, + pub codec: u64, } fn build_lotus_trace( @@ -383,26 +396,22 @@ fn build_lotus_trace( params: Option, value: TokenAmount, trace_iter: &mut impl Iterator, -) -> anyhow::Result { - let mut new_trace = LotusTrace { - msg: Message { - version: 0, +) -> anyhow::Result { + let params = params.unwrap_or_default(); + let mut new_trace = Trace { + msg: TraceMessage { from: Address::new_id(from), to, value, - sequence: 0, method_num: method, - params: params.map(|b| b.data).unwrap_or_default().into(), - gas_limit: 0, - gas_fee_cap: TokenAmount::default(), - gas_premium: TokenAmount::default(), + params: params.data, + codec: params.codec, }, - msg_receipt: LotusReceipt { + msg_ret: TraceReturn { exit_code: ExitCode::OK, - return_data: RawBytes::default(), - gas_used: 0, + return_data: Vec::new(), + codec: 0, }, - error: String::new(), gas_charges: vec![], subcalls: vec![], }; @@ -421,10 +430,11 @@ fn build_lotus_trace( )?); } ExecutionEvent::CallReturn(exit_code, return_data) => { - new_trace.msg_receipt = LotusReceipt { + let return_data = return_data.unwrap_or_default(); + new_trace.msg_ret = TraceReturn { exit_code, - return_data: return_data.map(|b| b.data).unwrap_or_default().into(), - gas_used: 0, + return_data: return_data.data, + codec: return_data.codec, }; return Ok(new_trace); } @@ -438,10 +448,10 @@ fn build_lotus_trace( _ => ExitCode::SYS_ASSERTION_FAILED, }; - new_trace.msg_receipt = LotusReceipt { + new_trace.msg_ret = TraceReturn { exit_code, return_data: Default::default(), - gas_used: 0, + codec: 0, }; return Ok(new_trace); } @@ -449,13 +459,20 @@ fn build_lotus_trace( name, compute_gas, other_gas, - elapsed: _, // TODO: thread timing through to lotus. + elapsed, }) => { new_trace.gas_charges.push(LotusGasCharge { name, total_gas: (compute_gas + other_gas).round_up(), compute_gas: compute_gas.round_up(), other_gas: other_gas.round_up(), + duration_nanos: elapsed + .get() + .copied() + .unwrap_or_default() + .as_nanos() + .try_into() + .unwrap_or(u64::MAX), }); } _ => (), // ignore unknown events. @@ -522,6 +539,12 @@ mod test { total_gas: initial_gas_charge.total().round_up(), compute_gas: initial_gas_charge.compute_gas.round_up(), other_gas: initial_gas_charge.other_gas.round_up(), + duration_nanos: initial_gas_charge + .elapsed + .get() + .copied() + .unwrap_or_default() + .as_nanos() as u64, } ); assert_eq!(lotus_trace.subcalls.len(), 2); From 6c4bf907a0535d6ab1077471def2787bc9d6008f Mon Sep 17 00:00:00 2001 From: Steven Allen Date: Wed, 1 Mar 2023 11:08:44 -0800 Subject: [PATCH 2/2] chore: remove todo --- rust/src/fvm/machine.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/rust/src/fvm/machine.rs b/rust/src/fvm/machine.rs index 505e516f..fa26fb30 100644 --- a/rust/src/fvm/machine.rs +++ b/rust/src/fvm/machine.rs @@ -303,7 +303,6 @@ fn fvm_machine_execute_message( let events_root = events_root.map(|cid| cid.to_bytes().into_boxed_slice().into()); - // TODO: Do something with the backtrace. Ok(FvmMachineExecuteResponse { exit_code: exit_code.value() as u64, return_val,