Skip to main content

iota_types/
event.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use std::str::FromStr;
6
7use anyhow::ensure;
8use iota_sdk_types::{Event, TransactionDigest};
9use serde::{Deserialize, Serialize};
10use serde_json::Value;
11use serde_with::serde_as;
12
13use crate::iota_serde::{BigInt, Readable};
14
15/// A universal IOTA event type encapsulating different types of events
16#[derive(Debug, Clone, Serialize, Deserialize)]
17pub struct EventEnvelope {
18    /// UTC timestamp in milliseconds since epoch (1/1/1970)
19    pub timestamp: u64,
20    /// Transaction digest of associated transaction
21    pub tx_digest: TransactionDigest,
22    /// Consecutive per-tx counter assigned to this event.
23    pub event_num: u64,
24    /// Specific event type
25    pub event: Event,
26    /// Move event's json value
27    pub parsed_json: Value,
28}
29/// Unique ID of an IOTA Event, the ID is a combination of transaction digest
30/// and event seq number.
31#[serde_as]
32#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Hash)]
33#[serde(rename_all = "camelCase")]
34pub struct EventID {
35    pub tx_digest: TransactionDigest,
36    #[serde_as(as = "Readable<BigInt<u64>, _>")]
37    pub event_seq: u64,
38}
39
40impl From<(TransactionDigest, u64)> for EventID {
41    fn from((tx_digest_num, event_seq_number): (TransactionDigest, u64)) -> Self {
42        Self {
43            tx_digest: tx_digest_num as TransactionDigest,
44            event_seq: event_seq_number,
45        }
46    }
47}
48
49impl From<EventID> for String {
50    fn from(id: EventID) -> Self {
51        format!("{:?}:{}", id.tx_digest, id.event_seq)
52    }
53}
54
55impl TryFrom<String> for EventID {
56    type Error = anyhow::Error;
57
58    fn try_from(value: String) -> Result<Self, Self::Error> {
59        let values = value.split(':').collect::<Vec<_>>();
60        ensure!(values.len() == 2, "Malformed EventID : {value}");
61        Ok((
62            TransactionDigest::from_str(values[0])?,
63            u64::from_str(values[1])?,
64        )
65            .into())
66    }
67}
68
69impl EventEnvelope {
70    pub fn new(
71        timestamp: u64,
72        tx_digest: TransactionDigest,
73        event_num: u64,
74        event: Event,
75        move_struct_json_value: Value,
76    ) -> Self {
77        Self {
78            timestamp,
79            tx_digest,
80            event_num,
81            event,
82            parsed_json: move_struct_json_value,
83        }
84    }
85}
86
87#[derive(Deserialize)]
88pub enum SystemEpochInfoEvent {
89    V1(SystemEpochInfoEventV1),
90    V2(SystemEpochInfoEventV2),
91}
92
93impl SystemEpochInfoEvent {
94    pub fn supply_change(&self) -> i64 {
95        match self {
96            SystemEpochInfoEvent::V1(event) => {
97                event.minted_tokens_amount as i64 - event.burnt_tokens_amount as i64
98            }
99            SystemEpochInfoEvent::V2(event) => {
100                event.minted_tokens_amount as i64 - event.burnt_tokens_amount as i64
101            }
102        }
103    }
104}
105
106impl From<Event> for SystemEpochInfoEvent {
107    fn from(event: Event) -> Self {
108        if event.is_system_epoch_info_event_v2() {
109            SystemEpochInfoEvent::V2(
110                bcs::from_bytes::<SystemEpochInfoEventV2>(&event.contents)
111                    .expect("event deserialization should succeed as type was pre-validated"),
112            )
113        } else {
114            SystemEpochInfoEvent::V1(
115                bcs::from_bytes::<SystemEpochInfoEventV1>(&event.contents)
116                    .expect("event deserialization should succeed as type was pre-validated"),
117            )
118        }
119    }
120}
121
122/// Event emitted in move code `fun advance_epoch` in protocol versions 1 to 3
123#[derive(Serialize, Deserialize, Default)]
124pub struct SystemEpochInfoEventV1 {
125    pub epoch: u64,
126    pub protocol_version: u64,
127    pub reference_gas_price: u64,
128    pub total_stake: u64,
129    pub storage_charge: u64,
130    pub storage_rebate: u64,
131    pub storage_fund_balance: u64,
132    pub total_gas_fees: u64,
133    pub total_stake_rewards_distributed: u64,
134    pub burnt_tokens_amount: u64,
135    pub minted_tokens_amount: u64,
136}
137
138/// Event emitted in move code `fun advance_epoch` in protocol versions 5 and
139/// later.
140/// This second version of the event includes the tips amount to show how much
141/// of the gas fees go to the validators when protocol_defined_base_fee is
142/// enabled in the protocol config.
143#[derive(Serialize, Deserialize, Default)]
144pub struct SystemEpochInfoEventV2 {
145    pub epoch: u64,
146    pub protocol_version: u64,
147    pub total_stake: u64,
148    pub storage_charge: u64,
149    pub storage_rebate: u64,
150    pub storage_fund_balance: u64,
151    pub total_gas_fees: u64,
152    pub total_stake_rewards_distributed: u64,
153    pub burnt_tokens_amount: u64,
154    pub minted_tokens_amount: u64,
155    pub tips_amount: u64,
156}