massa_models/
output_event.rs

1use crate::async_msg_id::{AsyncMessageId, AsyncMessageIdWrapper};
2use crate::deferred_calls::DeferredCallId;
3use crate::{address::Address, block_id::BlockId, operation::OperationId, slot::Slot};
4use serde::{Deserialize, Serialize};
5use std::cmp::Ordering;
6use std::{collections::VecDeque, fmt::Display};
7
8#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
9/// By product of a byte code execution
10pub struct SCOutputEvent {
11    /// context generated by the execution context
12    pub context: EventExecutionContext,
13    /// json data string
14    pub data: String,
15}
16
17impl PartialOrd for SCOutputEvent {
18    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
19        Some(self.cmp(other))
20    }
21}
22
23impl Ord for SCOutputEvent {
24    fn cmp(&self, other: &Self) -> Ordering {
25        (self.context.slot, self.context.index_in_slot)
26            .cmp(&(other.context.slot, other.context.index_in_slot))
27    }
28}
29
30impl Display for SCOutputEvent {
31    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
32        writeln!(f, "Context: {}", self.context)?;
33        writeln!(f, "Data: {}", self.data)
34    }
35}
36
37/// Context of the event (not generated by the user)
38#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
39pub struct EventExecutionContext {
40    /// when was it generated
41    pub slot: Slot,
42    /// block id if there was a block at that slot
43    pub block: Option<BlockId>,
44    /// if the event was generated during a read only execution
45    pub read_only: bool,
46    /// index of the event in the slot
47    pub index_in_slot: u64,
48    /// most recent at the end
49    pub call_stack: VecDeque<Address>,
50    /// origin operation id
51    pub origin_operation_id: Option<OperationId>,
52    /// if the event is final
53    pub is_final: bool,
54    /// if the sc that emitted this event failed
55    pub is_error: bool,
56    /// the deferred call id that is currently being executed
57    pub deferred_call_id: Option<DeferredCallId>,
58    /// the async message id that is currently being executed
59    pub async_msg_id: Option<AsyncMessageId>,
60}
61
62impl Display for EventExecutionContext {
63    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64        writeln!(f, "Slot: {} at index: {}", self.slot, self.index_in_slot)?;
65
66        writeln!(
67            f,
68            "{}",
69            if self.read_only {
70                "Read only execution"
71            } else {
72                "On chain execution"
73            }
74        )?;
75        if let Some(id) = self.block {
76            writeln!(f, "Block id: {}", id)?;
77        }
78        if let Some(id) = self.origin_operation_id {
79            writeln!(f, "Origin operation id: {}", id)?;
80        }
81        if let Some(id) = &self.deferred_call_id {
82            writeln!(f, "Deferred call id: {}", id)?;
83        }
84        if let Some(id) = self.async_msg_id {
85            let wrapper = AsyncMessageIdWrapper(id);
86            writeln!(f, "Async message id: {}", wrapper)?;
87        }
88        writeln!(
89            f,
90            "Call stack: {}",
91            self.call_stack
92                .iter()
93                .map(|a| format!("{}", a))
94                .collect::<Vec<_>>()
95                .join(",")
96        )
97    }
98}