diem_types/
event.rs

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