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