1use crate::{
9 event::EventKey, ledger_info::LedgerInfo, proof::EventProof,
10 transaction::Version,
11};
12use anyhow::{ensure, Result};
13use diem_crypto::hash::CryptoHash;
14use diem_crypto_derive::{BCSCryptoHash, CryptoHasher};
15
16#[cfg(any(test, feature = "fuzzing"))]
17use proptest_derive::Arbitrary;
18use serde::{Deserialize, Serialize};
19use std::ops::Deref;
20
21#[derive(
23 Hash,
24 Clone,
25 Eq,
26 PartialEq,
27 Serialize,
28 Deserialize,
29 CryptoHasher,
30 BCSCryptoHash,
31)]
32pub enum ContractEvent {
33 V0(ContractEventV0),
34}
35
36impl ContractEvent {
37 pub fn new(key: EventKey, event_data: Vec<u8>) -> Self {
38 ContractEvent::V0(ContractEventV0::new(key, event_data))
39 }
40}
41
42impl Deref for ContractEvent {
45 type Target = ContractEventV0;
46
47 fn deref(&self) -> &Self::Target {
48 match self {
49 ContractEvent::V0(event) => event,
50 }
51 }
52}
53
54#[derive(Hash, Clone, Eq, PartialEq, Serialize, Deserialize, CryptoHasher)]
56pub struct ContractEventV0 {
57 key: EventKey,
59 #[serde(with = "serde_bytes")]
61 event_data: Vec<u8>,
62}
63
64impl ContractEventV0 {
65 pub fn new(key: EventKey, event_data: Vec<u8>) -> Self {
66 Self { key, event_data }
67 }
68
69 pub fn key(&self) -> &EventKey { &self.key }
70
71 pub fn event_data(&self) -> &[u8] { &self.event_data }
72}
73
74impl std::fmt::Debug for ContractEvent {
75 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76 write!(
77 f,
78 "ContractEvent {{ key: {:?}, event_data: {:?} }}",
79 self.key,
80 hex::encode(&self.event_data)
81 )
82 }
83}
84
85impl std::fmt::Display for ContractEvent {
86 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
87 write!(f, "{:?}", self)
88 }
89}
90
91#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
92#[cfg_attr(any(test, feature = "fuzzing"), derive(Arbitrary))]
93pub struct EventWithProof {
94 pub transaction_version: u64, pub event_index: u64,
96 pub event: ContractEvent,
97 pub proof: EventProof,
98}
99
100impl std::fmt::Display for EventWithProof {
101 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
102 write!(
103 f,
104 "EventWithProof {{ \n\ttransaction_version: {}, \n\tevent_index: {}, \
105 \n\tevent: {}, \n\tproof: {:?} \n}}",
106 self.transaction_version, self.event_index, self.event, self.proof
107 )
108 }
109}
110
111impl EventWithProof {
112 pub fn new(
114 transaction_version: Version, event_index: u64, event: ContractEvent,
115 proof: EventProof,
116 ) -> Self {
117 Self {
118 transaction_version,
119 event_index,
120 event,
121 proof,
122 }
123 }
124
125 pub fn verify(
136 &self, ledger_info: &LedgerInfo, event_key: &EventKey,
137 _sequence_number: u64, transaction_version: Version, event_index: u64,
138 ) -> Result<()> {
139 ensure!(
140 self.event.key() == event_key,
141 "Event key ({}) not expected ({}).",
142 self.event.key(),
143 *event_key,
144 );
145 ensure!(
146 self.transaction_version == transaction_version,
147 "Transaction version ({}) not expected ({}).",
148 self.transaction_version,
149 transaction_version,
150 );
151 ensure!(
152 self.event_index == event_index,
153 "Event index ({}) not expected ({}).",
154 self.event_index,
155 event_index,
156 );
157
158 self.proof.verify(
159 ledger_info,
160 self.event.hash(),
161 transaction_version,
162 event_index,
163 )?;
164
165 Ok(())
166 }
167}