dusk_node_data/events/
contract.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4//
5// Copyright (c) DUSK NETWORK. All rights reserved.
6
7//! This module defines the contract event type and related types.
8
9use dusk_core::abi::{ContractId, Event};
10use serde::{Deserialize, Serialize};
11
12pub const ORIGIN_HASH_BYTES: usize = 32;
13/// Origin hash of a contract event. This is in most cases the transaction hash.
14/// In the case of a reward or slash event, it is the block hash.
15pub type OriginHash = [u8; ORIGIN_HASH_BYTES];
16
17/// Contract event with origin `OriginHash`.
18#[serde_with::serde_as]
19#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
20pub struct ContractTxEvent {
21    pub event: ContractEvent,
22    #[serde_as(as = "serde_with::hex::Hex")]
23    pub origin: OriginHash,
24}
25
26/// Wrapper around a contract event that is to be archived or sent to a
27/// websocket client.
28#[serde_with::serde_as]
29#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
30pub struct ContractEvent {
31    pub target: ContractId,
32    pub topic: String,
33    #[serde_as(as = "serde_with::hex::Hex")]
34    pub data: Vec<u8>,
35}
36
37impl From<Event> for ContractEvent {
38    fn from(event: Event) -> Self {
39        Self {
40            target: event.source,
41            topic: event.topic,
42            data: event.data,
43        }
44    }
45}
46
47impl From<ContractEvent> for Event {
48    fn from(contract_event: ContractEvent) -> Self {
49        Event {
50            source: contract_event.target,
51            topic: contract_event.topic,
52            data: contract_event.data,
53        }
54    }
55}
56
57#[cfg(test)]
58mod tests {
59    use dusk_core::abi::CONTRACT_ID_BYTES;
60
61    use super::*;
62
63    fn exec_core_event() -> Event {
64        Event {
65            source: ContractId::from_bytes([0; CONTRACT_ID_BYTES]),
66            topic: "contract".to_string(),
67            data: vec![1, 2, 3],
68        }
69    }
70
71    #[test]
72    fn test_converting_contract_event() {
73        let contract_event: ContractEvent = exec_core_event().into();
74
75        assert_eq!(Event::from(contract_event), exec_core_event());
76    }
77
78    #[test]
79    fn test_serialize_contract_event() {
80        let event: ContractEvent = exec_core_event().into();
81        let json_event = serde_json::to_string(&event).unwrap();
82        assert_eq!(event, serde_json::from_str(&json_event).unwrap());
83
84        let events: Vec<ContractEvent> = vec![event.clone(), event];
85        let json_events = serde_json::to_string(&events).unwrap();
86        assert_eq!(
87            events,
88            serde_json::from_str::<Vec<ContractEvent>>(&json_events).unwrap()
89        );
90
91        let empty_events: Vec<ContractEvent> = vec![];
92        let empty_json_events = serde_json::to_string(&empty_events).unwrap();
93        assert_eq!(
94            empty_events,
95            serde_json::from_str::<Vec<ContractEvent>>(&empty_json_events)
96                .unwrap()
97        );
98    }
99}