Skip to main content

diem_types/
event.rs

1// Copyright (c) The Diem Core Contributors
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::account_address::AccountAddress;
5use hex::FromHex;
6#[cfg(any(test, feature = "fuzzing"))]
7use proptest_derive::Arbitrary;
8#[cfg(any(test, feature = "fuzzing"))]
9use rand::{rngs::OsRng, RngCore};
10use serde::{de, ser, Deserialize, Serialize};
11use std::{
12    convert::{TryFrom, TryInto},
13    fmt,
14    str::FromStr,
15};
16
17/// A struct that represents a globally unique id for an Event stream that a user can listen to.
18/// By design, the lower part of EventKey is the same as account address.
19#[derive(Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
20#[cfg_attr(any(test, feature = "fuzzing"), derive(Arbitrary))]
21pub struct EventKey([u8; EventKey::LENGTH]);
22
23impl EventKey {
24    /// Construct a new EventKey from a byte array slice.
25    pub fn new(key: [u8; Self::LENGTH]) -> Self {
26        EventKey(key)
27    }
28
29    /// The number of bytes in an EventKey.
30    pub const LENGTH: usize = AccountAddress::LENGTH + 8;
31
32    /// Get the byte representation of the event key.
33    pub fn as_bytes(&self) -> &[u8] {
34        &self.0
35    }
36
37    /// Convert event key into a byte array.
38    pub fn to_vec(&self) -> Vec<u8> {
39        self.0.to_vec()
40    }
41
42    /// Get the account address part in this event key
43    pub fn get_creator_address(&self) -> AccountAddress {
44        AccountAddress::try_from(&self.0[EventKey::LENGTH - AccountAddress::LENGTH..])
45            .expect("get_creator_address failed")
46    }
47
48    /// If this is the `ith` EventKey` created by `get_creator_address()`, return `i`
49    pub fn get_creation_number(&self) -> u64 {
50        u64::from_le_bytes(self.0[0..8].try_into().unwrap())
51    }
52
53    #[cfg(any(test, feature = "fuzzing"))]
54    /// Create a random event key for testing
55    pub fn random() -> Self {
56        let mut rng = OsRng;
57        let salt = rng.next_u64();
58        EventKey::new_from_address(&AccountAddress::random(), salt)
59    }
60
61    /// Create a unique handle by using an AccountAddress and a counter.
62    pub fn new_from_address(addr: &AccountAddress, salt: u64) -> Self {
63        let mut output_bytes = [0; Self::LENGTH];
64        let (lhs, rhs) = output_bytes.split_at_mut(8);
65        lhs.copy_from_slice(&salt.to_le_bytes());
66        rhs.copy_from_slice(addr.as_ref());
67        EventKey(output_bytes)
68    }
69
70    pub fn from_hex<T: AsRef<[u8]>>(hex: T) -> Result<Self, EventKeyParseError> {
71        <[u8; Self::LENGTH]>::from_hex(hex)
72            .map_err(|_| EventKeyParseError)
73            .map(Self)
74    }
75
76    pub fn from_bytes<T: AsRef<[u8]>>(bytes: T) -> Result<Self, EventKeyParseError> {
77        <[u8; Self::LENGTH]>::try_from(bytes.as_ref())
78            .map_err(|_| EventKeyParseError)
79            .map(Self)
80    }
81}
82
83impl FromStr for EventKey {
84    type Err = EventKeyParseError;
85
86    fn from_str(s: &str) -> Result<Self, EventKeyParseError> {
87        EventKey::from_hex(s)
88    }
89}
90
91impl From<EventKey> for [u8; EventKey::LENGTH] {
92    fn from(event_key: EventKey) -> Self {
93        event_key.0
94    }
95}
96
97impl From<&EventKey> for [u8; EventKey::LENGTH] {
98    fn from(event_key: &EventKey) -> Self {
99        event_key.0
100    }
101}
102
103impl ser::Serialize for EventKey {
104    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
105    where
106        S: ser::Serializer,
107    {
108        if serializer.is_human_readable() {
109            self.to_string().serialize(serializer)
110        } else {
111            // In order to preserve the Serde data model and help analysis tools,
112            // make sure to wrap our value in a container with the same name
113            // as the original type.
114            serializer.serialize_newtype_struct("EventKey", serde_bytes::Bytes::new(&self.0))
115        }
116    }
117}
118
119impl<'de> de::Deserialize<'de> for EventKey {
120    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
121    where
122        D: de::Deserializer<'de>,
123    {
124        use serde::de::Error;
125
126        if deserializer.is_human_readable() {
127            let s = <String>::deserialize(deserializer)?;
128            EventKey::from_hex(s).map_err(D::Error::custom)
129        } else {
130            // See comment in serialize.
131            #[derive(::serde::Deserialize)]
132            #[serde(rename = "EventKey")]
133            struct Value<'a>(&'a [u8]);
134
135            let value = Value::deserialize(deserializer)?;
136            Self::try_from(value.0).map_err(D::Error::custom)
137        }
138    }
139}
140
141impl fmt::LowerHex for EventKey {
142    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
143        if f.alternate() {
144            write!(f, "0x")?;
145        }
146
147        for byte in &self.0 {
148            write!(f, "{:02x}", byte)?;
149        }
150
151        Ok(())
152    }
153}
154
155impl fmt::Display for EventKey {
156    fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result {
157        write!(f, "{:x}", self)
158    }
159}
160
161impl fmt::Debug for EventKey {
162    fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result {
163        write!(f, "EventKey({:x})", self)
164    }
165}
166
167impl TryFrom<&[u8]> for EventKey {
168    type Error = EventKeyParseError;
169
170    /// Tries to convert the provided byte array into Event Key.
171    fn try_from(bytes: &[u8]) -> Result<EventKey, EventKeyParseError> {
172        Self::from_bytes(bytes)
173    }
174}
175
176#[derive(Clone, Copy, Debug)]
177pub struct EventKeyParseError;
178
179impl fmt::Display for EventKeyParseError {
180    fn fmt(&self, f: &mut fmt::Formatter) -> std::fmt::Result {
181        write!(f, "unable to parse EventKey")
182    }
183}
184
185impl std::error::Error for EventKeyParseError {}
186
187/// A Rust representation of an Event Handle Resource.
188#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
189pub struct EventHandle {
190    /// Number of events in the event stream.
191    count: u64,
192    /// The associated globally unique key that is used as the key to the EventStore.
193    key: EventKey,
194}
195
196impl EventHandle {
197    /// Constructs a new Event Handle
198    pub fn new(key: EventKey, count: u64) -> Self {
199        EventHandle { count, key }
200    }
201
202    /// Return the key to where this event is stored in EventStore.
203    pub fn key(&self) -> &EventKey {
204        &self.key
205    }
206
207    /// Return the counter for the handle
208    pub fn count(&self) -> u64 {
209        self.count
210    }
211
212    #[cfg(any(test, feature = "fuzzing"))]
213    pub fn count_mut(&mut self) -> &mut u64 {
214        &mut self.count
215    }
216
217    #[cfg(any(test, feature = "fuzzing"))]
218    /// Create a random event handle for testing
219    pub fn random_handle(count: u64) -> Self {
220        Self {
221            key: EventKey::random(),
222            count,
223        }
224    }
225
226    #[cfg(any(test, feature = "fuzzing"))]
227    /// Derive a unique handle by using an AccountAddress and a counter.
228    pub fn new_from_address(addr: &AccountAddress, salt: u64) -> Self {
229        Self {
230            key: EventKey::new_from_address(addr, salt),
231            count: 0,
232        }
233    }
234}
235#[cfg(test)]
236mod tests {
237    use super::EventKey;
238
239    #[test]
240    fn test_display_impls() {
241        let hex = "1000000000000000ca843279e3427144cead5e4d5999a3d0";
242
243        let key = EventKey::from_hex(hex).unwrap();
244
245        assert_eq!(format!("{}", key), hex);
246        assert_eq!(format!("{:x}", key), hex);
247
248        assert_eq!(format!("{:#x}", key), format!("0x{}", hex));
249    }
250
251    #[test]
252    fn test_invalid_length() {
253        let bytes = vec![1; 123];
254        EventKey::from_bytes(bytes).unwrap_err();
255    }
256
257    #[test]
258    fn test_deserialize_from_json_value() {
259        let key = EventKey::random();
260        let json_value = serde_json::to_value(key).unwrap();
261        let key2: EventKey = serde_json::from_value(json_value).unwrap();
262        assert_eq!(key, key2);
263    }
264
265    #[test]
266    fn test_serde_json() {
267        let hex = "1000000000000000ca843279e3427144cead5e4d5999a3d0";
268        let json_hex = "\"1000000000000000ca843279e3427144cead5e4d5999a3d0\"";
269
270        let key = EventKey::from_hex(hex).unwrap();
271
272        let json = serde_json::to_string(&key).unwrap();
273        let json_key: EventKey = serde_json::from_str(json_hex).unwrap();
274
275        assert_eq!(json, json_hex);
276        assert_eq!(key, json_key);
277    }
278}