1use self::ExecutionEvent as EShim;
4use crate::shim::{
5 address::Address as ShimAddress, econ::TokenAmount as ShimTokenAmount,
6 error::ExitCode as ShimExitCode, gas::GasCharge as ShimGasCharge,
7 kernel::SyscallError as ShimSyscallError, state_tree::ActorID as ShimActorId,
8 state_tree::ActorState as ShimActorState,
9};
10use cid::Cid;
11use fvm_ipld_encoding::{RawBytes, ipld_block::IpldBlock};
12use fvm2::trace::ExecutionEvent as E2;
13use fvm3::trace::ExecutionEvent as E3;
14use fvm4::trace::{ExecutionEvent as E4, IpldOperation};
15use itertools::Either;
16
17#[derive(Debug, Clone)]
18pub enum ExecutionEvent {
19 GasCharge(ShimGasCharge),
20 Call(Call),
21 CallReturn(CallReturn),
22 CallAbort(ShimExitCode),
23 CallError(ShimSyscallError),
24 Log(String),
25 InvokeActor(Either<Cid, InvokeActor>),
26 #[allow(dead_code)]
27 Ipld {
28 op: IpldOperation,
29 cid: Cid,
30 size: usize,
31 },
32 Unknown(Either<E3, Either<E4, E2>>),
33}
34
35#[derive(Debug, Clone, Eq, PartialEq)]
36pub struct CallReturn {
37 pub exit_code: Option<ShimExitCode>,
38 pub data: Either<RawBytes, Option<IpldBlock>>,
39}
40
41#[derive(Debug, Clone, Eq, PartialEq)]
42pub struct Call {
43 pub from: u64,
45 pub to: ShimAddress,
46 pub method_num: u64,
47 pub params: Either<RawBytes, Option<IpldBlock>>,
48 pub value: ShimTokenAmount,
49 pub gas_limit: Option<u64>,
50 pub read_only: Option<bool>,
51}
52
53#[derive(Debug, Clone, Eq, PartialEq)]
54pub struct InvokeActor {
55 pub id: ShimActorId,
56 pub state: ShimActorState,
57}
58
59impl From<E2> for ExecutionEvent {
60 fn from(value: E2) -> Self {
61 match value {
62 E2::GasCharge(gc) => EShim::GasCharge(gc.into()),
63 E2::Call {
64 from,
65 to,
66 method,
67 params,
68 value,
69 } => EShim::Call(Call {
70 from,
71 to: to.into(),
72 method_num: method,
73 params: Either::Left(params),
74 value: value.into(),
75 gas_limit: None,
76 read_only: None,
77 }),
78 E2::CallReturn(data) => EShim::CallReturn(CallReturn {
79 exit_code: None,
80 data: Either::Left(data),
81 }),
82 E2::CallAbort(ab) => EShim::CallAbort(ab.into()),
83 E2::CallError(err) => EShim::CallError(err.into()),
84 E2::Log(s) => EShim::Log(s),
85 e => EShim::Unknown(Either::Right(Either::Right(e))),
86 }
87 }
88}
89
90impl From<E3> for ExecutionEvent {
91 fn from(value: E3) -> Self {
92 match value {
93 E3::GasCharge(gc) => EShim::GasCharge(gc.into()),
94 E3::Call {
95 from,
96 to,
97 method,
98 params,
99 value,
100 gas_limit,
101 read_only,
102 } => EShim::Call(Call {
103 from,
104 to: to.into(),
105 method_num: method,
106 params: Either::Right(params),
107 value: value.into(),
108 gas_limit: Some(gas_limit),
109 read_only: Some(read_only),
110 }),
111 E3::CallReturn(exit_code, data) => EShim::CallReturn(CallReturn {
112 exit_code: Some(exit_code.into()),
113 data: Either::Right(data),
114 }),
115 E3::CallError(err) => EShim::CallError(err.into()),
116 E3::InvokeActor { id, state } => EShim::InvokeActor(Either::Right(InvokeActor {
117 id,
118 state: state.into(),
119 })),
120 e => EShim::Unknown(Either::Left(e)),
121 }
122 }
123}
124
125impl From<E4> for ExecutionEvent {
126 fn from(value: E4) -> Self {
127 match value {
128 E4::GasCharge(gc) => EShim::GasCharge(gc.into()),
129 E4::Call {
130 from,
131 to,
132 method,
133 params,
134 value,
135 gas_limit,
136 read_only,
137 } => EShim::Call(Call {
138 from,
139 to: to.into(),
140 method_num: method,
141 params: Either::Right(params),
142 value: value.into(),
143 gas_limit: Some(gas_limit),
144 read_only: Some(read_only),
145 }),
146 E4::CallReturn(exit_code, data) => EShim::CallReturn(CallReturn {
147 exit_code: Some(exit_code.into()),
148 data: Either::Right(data),
149 }),
150 E4::CallError(err) => EShim::CallError(err.into()),
151 E4::InvokeActor { id, state } => EShim::InvokeActor(Either::Right(InvokeActor {
152 id,
153 state: state.into(),
154 })),
155 E4::Log(s) => EShim::Log(s),
156 E4::Ipld { op, cid, size } => EShim::Ipld { op, cid, size },
157 e => EShim::Unknown(Either::Right(Either::Left(e))),
158 }
159 }
160}