1use cfx_bytes::Bytes;
6
7use crate::AddressPocket;
8use cfx_types::{Address, Bloom, BloomInput, Space, U256};
9use cfx_vm_types::{ActionParams, CallType, CreateType};
10use rlp::{Decodable, DecoderError, Encodable, Rlp, RlpStream};
11use rlp_derive::{RlpDecodable, RlpEncodable};
12use serde::{ser::SerializeStruct, Serialize, Serializer};
13use strum_macros::EnumDiscriminants;
14
15#[derive(Debug, Clone, PartialEq, RlpEncodable, Serialize)]
18#[serde(rename_all = "camelCase")]
19pub struct Call {
20 pub space: Space,
22 pub from: Address,
24 pub to: Address,
26 pub value: U256,
28 pub gas: U256,
30 pub input: Bytes,
32 pub call_type: CallType,
34}
35
36impl Decodable for Call {
37 fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
38 match rlp.item_count()? {
39 6 => Ok(Call {
40 space: Space::Native,
41 from: rlp.val_at(0)?,
42 to: rlp.val_at(1)?,
43 value: rlp.val_at(2)?,
44 gas: rlp.val_at(3)?,
45 input: rlp.val_at(4)?,
46 call_type: rlp.val_at(5)?,
47 }),
48 7 => Ok(Call {
49 space: rlp.val_at(0)?,
50 from: rlp.val_at(1)?,
51 to: rlp.val_at(2)?,
52 value: rlp.val_at(3)?,
53 gas: rlp.val_at(4)?,
54 input: rlp.val_at(5)?,
55 call_type: rlp.val_at(6)?,
56 }),
57 _ => Err(DecoderError::RlpInvalidLength),
58 }
59 }
60}
61
62impl From<ActionParams> for Call {
63 fn from(p: ActionParams) -> Self {
64 match p.call_type {
65 CallType::DelegateCall | CallType::CallCode => Call {
66 space: p.space,
67 from: p.address,
68 to: p.code_address,
69 value: p.value.value(),
70 gas: p.gas,
71 input: p.data.unwrap_or_else(Vec::new),
72 call_type: p.call_type,
73 },
74 _ => Call {
75 space: p.space,
76 from: p.sender,
77 to: p.address,
78 value: p.value.value(),
79 gas: p.gas,
80 input: p.data.unwrap_or_else(Vec::new),
81 call_type: p.call_type,
82 },
83 }
84 }
85}
86
87impl Call {
88 pub fn bloom(&self) -> Bloom {
91 let mut bloom = Bloom::default();
92 bloom.accrue(BloomInput::Raw(self.from.as_bytes()));
93 bloom.accrue(BloomInput::Raw(self.to.as_bytes()));
94 bloom
95 }
96}
97
98#[derive(Debug, PartialEq, Clone, Serialize)]
100#[serde(rename_all = "lowercase")]
101pub enum Outcome {
102 Success,
103 Reverted,
104 Fail,
105}
106
107impl Encodable for Outcome {
108 fn rlp_append(&self, s: &mut RlpStream) {
109 let v = match *self {
110 Outcome::Success => 0u32,
111 Outcome::Reverted => 1,
112 Outcome::Fail => 2,
113 };
114 Encodable::rlp_append(&v, s);
115 }
116}
117
118impl Decodable for Outcome {
119 fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
120 rlp.as_val().and_then(|v| {
121 Ok(match v {
122 0u32 => Outcome::Success,
123 1 => Outcome::Reverted,
124 2 => Outcome::Fail,
125 _ => {
126 return Err(DecoderError::Custom(
127 "Invalid value of Outcome item",
128 ));
129 }
130 })
131 })
132 }
133}
134
135#[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable, Serialize)]
137#[serde(rename_all = "camelCase")]
138pub struct CallResult {
139 pub outcome: Outcome,
141 pub gas_left: U256,
143 pub return_data: Bytes,
145}
146
147#[derive(Debug, Clone, PartialEq, RlpEncodable, Serialize)]
150#[serde(rename_all = "camelCase")]
151pub struct Create {
152 pub space: Space,
154 pub from: Address,
156 pub value: U256,
158 pub gas: U256,
160 pub init: Bytes,
162 pub create_type: CreateType,
164}
165
166impl Decodable for Create {
167 fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
168 match rlp.item_count()? {
169 5 => Ok(Create {
170 space: Space::Native,
171 from: rlp.val_at(0)?,
172 value: rlp.val_at(1)?,
173 gas: rlp.val_at(2)?,
174 init: rlp.val_at(3)?,
175 create_type: rlp.val_at(4)?,
176 }),
177 6 => Ok(Create {
178 space: rlp.val_at(0)?,
179 from: rlp.val_at(1)?,
180 value: rlp.val_at(2)?,
181 gas: rlp.val_at(3)?,
182 init: rlp.val_at(4)?,
183 create_type: rlp.val_at(5)?,
184 }),
185 _ => Err(DecoderError::RlpInvalidLength),
186 }
187 }
188}
189
190impl From<ActionParams> for Create {
191 fn from(p: ActionParams) -> Self {
192 Create {
193 space: p.space,
194 from: p.sender,
195 value: p.value.value(),
196 gas: p.gas,
197 init: p.code.map_or_else(Vec::new, |c| (*c).clone()),
198 create_type: p.create_type,
199 }
200 }
201}
202
203impl Create {
204 pub fn bloom(&self) -> Bloom {
207 BloomInput::Raw(self.from.as_bytes()).into()
208 }
209}
210
211#[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable, Serialize)]
213#[serde(rename_all = "camelCase")]
214pub struct CreateResult {
215 pub outcome: Outcome,
217 pub addr: Address,
219 pub gas_left: U256,
221 pub return_data: Bytes,
223}
224
225impl CreateResult {
226 pub fn bloom(&self) -> Bloom {
229 if self.outcome == Outcome::Success {
230 BloomInput::Raw(self.addr.as_bytes()).into()
231 } else {
232 Bloom::default()
233 }
234 }
235}
236
237#[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable)]
240pub struct InternalTransferAction {
241 pub from: AddressPocket,
243 pub to: AddressPocket,
245 pub value: U256,
247}
248
249impl Serialize for InternalTransferAction {
250 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
251 where S: Serializer {
252 let mut s = serializer.serialize_struct("InternalTransferAction", 5)?;
253 s.serialize_field("from", &self.from.inner_address_or_default())?;
254 s.serialize_field("fromPocket", &*self.from.pocket())?;
255 s.serialize_field("fromSpace", &*self.from.space())?;
256 s.serialize_field("to", &self.to.inner_address_or_default())?;
257 s.serialize_field("toPocket", &*self.to.pocket())?;
258 s.serialize_field("toSpace", &*self.to.space())?;
259 s.serialize_field("value", &self.value)?;
260 s.end()
261 }
262}
263
264impl InternalTransferAction {
265 pub fn bloom(&self) -> Bloom {
266 let mut bloom = Bloom::default();
267 bloom.accrue(BloomInput::Raw(
268 self.from.inner_address_or_default().as_ref(),
269 ));
270 bloom.accrue(BloomInput::Raw(
271 self.to.inner_address_or_default().as_ref(),
272 ));
273 bloom
274 }
275}
276
277#[derive(Debug, Clone, PartialEq, RlpEncodable, RlpDecodable, Serialize)]
278pub struct SetAuth {
279 pub space: Space,
280 pub address: Address,
282 pub chain_id: U256,
283 pub nonce: U256,
284 pub outcome: SetAuthOutcome,
286 pub author: Option<Address>,
288}
289
290impl SetAuth {
291 pub fn bloom(&self) -> Bloom {
293 let mut bloom = Bloom::default();
294 bloom.accrue(BloomInput::Raw(self.address.as_bytes()));
295 if self.author.is_some() {
296 bloom.accrue(BloomInput::Raw(
297 self.author.as_ref().unwrap().as_bytes(),
298 ));
299 }
300 bloom
301 }
302}
303
304#[derive(Debug, PartialEq, Copy, Clone, Serialize)]
306#[serde(rename_all = "snake_case")]
307pub enum SetAuthOutcome {
308 Success,
309 InvalidChainId,
310 NonceOverflow,
311 AccountCanNotSetAuth,
313 InvalidNonce,
314 InvalidSignature,
315}
316
317impl Encodable for SetAuthOutcome {
318 fn rlp_append(&self, s: &mut RlpStream) {
319 let v = match *self {
320 SetAuthOutcome::Success => 0u32,
321 SetAuthOutcome::InvalidChainId => 1,
322 SetAuthOutcome::NonceOverflow => 2,
323 SetAuthOutcome::AccountCanNotSetAuth => 3,
324 SetAuthOutcome::InvalidNonce => 4,
325 SetAuthOutcome::InvalidSignature => 5,
326 };
327 Encodable::rlp_append(&v, s);
328 }
329}
330
331impl Decodable for SetAuthOutcome {
332 fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
333 rlp.as_val().and_then(|v| {
334 Ok(match v {
335 0u32 => SetAuthOutcome::Success,
336 1 => SetAuthOutcome::InvalidChainId,
337 2 => SetAuthOutcome::NonceOverflow,
338 3 => SetAuthOutcome::AccountCanNotSetAuth,
339 4 => SetAuthOutcome::InvalidNonce,
340 5 => SetAuthOutcome::InvalidSignature,
341 _ => {
342 return Err(DecoderError::Custom(
343 "Invalid value of SetAuthOutcome item",
344 ));
345 }
346 })
347 })
348 }
349}
350
351#[derive(
353 Clone, Copy, Debug, PartialEq, Eq, Serialize, RlpEncodable, RlpDecodable,
354)]
355#[serde(rename_all = "camelCase")]
356pub struct SelfDestructAction {
357 pub space: Space,
359 pub address: Address,
361 pub balance: U256,
363 pub refund_address: Address,
365}
366
367impl SelfDestructAction {
368 pub fn bloom(&self) -> Bloom {
371 let mut bloom = Bloom::default();
372 bloom.accrue(BloomInput::Raw(self.address.as_bytes()));
373 bloom
374 }
375}
376
377#[derive(Debug, Clone, PartialEq, EnumDiscriminants)]
379#[strum_discriminants(name(ActionType))]
380pub enum Action {
381 Call(Call),
383 Create(Create),
385 CallResult(CallResult),
387 CreateResult(CreateResult),
389 InternalTransferAction(InternalTransferAction),
391 SetAuth(SetAuth),
393 SelfDestruct(SelfDestructAction),
395}
396
397impl Encodable for Action {
398 fn rlp_append(&self, s: &mut RlpStream) {
399 s.begin_list(2);
400 match *self {
401 Action::Call(ref call) => {
402 s.append(&0u8);
403 s.append(call);
404 }
405 Action::Create(ref create) => {
406 s.append(&1u8);
407 s.append(create);
408 }
409 Action::CallResult(ref call_result) => {
410 s.append(&2u8);
411 s.append(call_result);
412 }
413 Action::CreateResult(ref create_result) => {
414 s.append(&3u8);
415 s.append(create_result);
416 }
417 Action::InternalTransferAction(ref internal_action) => {
418 s.append(&4u8);
419 s.append(internal_action);
420 }
421 Action::SetAuth(ref set_auth_action) => {
422 s.append(&5u8);
423 s.append(set_auth_action);
424 }
425 Action::SelfDestruct(ref selfdestruct_action) => {
426 s.append(&6u8);
427 s.append(selfdestruct_action);
428 }
429 }
430 }
431}
432
433impl Decodable for Action {
434 fn decode(rlp: &Rlp) -> Result<Self, DecoderError> {
435 let action_type: u8 = rlp.val_at(0)?;
436 match action_type {
437 0 => rlp.val_at(1).map(Action::Call),
438 1 => rlp.val_at(1).map(Action::Create),
439 2 => rlp.val_at(1).map(Action::CallResult),
440 3 => rlp.val_at(1).map(Action::CreateResult),
441 4 => rlp.val_at(1).map(Action::InternalTransferAction),
442 5 => rlp.val_at(1).map(Action::SetAuth),
443 6 => rlp.val_at(1).map(Action::SelfDestruct),
444 _ => Err(DecoderError::Custom("Invalid action type.")),
445 }
446 }
447}
448
449impl Action {
450 pub fn bloom(&self) -> Bloom {
452 match *self {
453 Action::Call(ref call) => call.bloom(),
454 Action::Create(ref create) => create.bloom(),
455 Action::CallResult(_) => Bloom::default(),
456 Action::CreateResult(ref create_result) => create_result.bloom(),
457 Action::InternalTransferAction(ref internal_action) => {
458 internal_action.bloom()
459 }
460 Action::SetAuth(ref set_auth_action) => set_auth_action.bloom(),
461 Action::SelfDestruct(ref selfdestruct_action) => {
462 selfdestruct_action.bloom()
463 }
464 }
465 }
466}