Skip to main content

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};
11use serde_with::As;
12use serde_with::hex::Hex;
13
14pub const ORIGIN_HASH_BYTES: usize = 32;
15/// Origin hash of a contract event. This is in most cases the transaction hash.
16/// In the case of a reward or slash event, it is the block hash.
17pub type OriginHash = [u8; ORIGIN_HASH_BYTES];
18
19/// Contract event with origin `OriginHash`.
20#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
21pub struct ContractTxEvent {
22    pub event: ContractEvent,
23    #[serde(with = "As::<Hex>")]
24    pub origin: OriginHash,
25}
26
27/// Wrapper around a contract event that is to be archived or sent to a
28/// websocket client.
29#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
30pub struct ContractEvent {
31    pub target: ContractId,
32    pub topic: String,
33    #[serde(with = "As::<Hex>")]
34    pub data: Vec<u8>,
35    #[serde(default)]
36    pub reverted: bool,
37}
38
39impl From<Event> for ContractEvent {
40    fn from(event: Event) -> Self {
41        Self {
42            target: event.source,
43            topic: event.topic,
44            data: event.data,
45            reverted: event.reverted,
46        }
47    }
48}
49
50impl From<ContractEvent> for Event {
51    fn from(contract_event: ContractEvent) -> Self {
52        Event {
53            source: contract_event.target,
54            topic: contract_event.topic,
55            data: contract_event.data,
56            reverted: contract_event.reverted,
57        }
58    }
59}
60
61#[cfg(test)]
62mod tests {
63    use dusk_core::abi::CONTRACT_ID_BYTES;
64
65    use super::*;
66
67    fn exec_core_event() -> Event {
68        Event {
69            source: ContractId::from_bytes([0; CONTRACT_ID_BYTES]),
70            topic: "contract".to_string(),
71            data: vec![1, 2, 3],
72            reverted: false,
73        }
74    }
75
76    #[test]
77    fn test_converting_contract_event() {
78        let contract_event: ContractEvent = exec_core_event().into();
79
80        assert_eq!(Event::from(contract_event), exec_core_event());
81    }
82
83    #[test]
84    fn test_serialize_contract_event() {
85        let event: ContractEvent = exec_core_event().into();
86        let json_event = serde_json::to_string(&event).unwrap();
87        assert_eq!(event, serde_json::from_str(&json_event).unwrap());
88
89        let events: Vec<ContractEvent> = vec![event.clone(), event];
90        let json_events = serde_json::to_string(&events).unwrap();
91        assert_eq!(
92            events,
93            serde_json::from_str::<Vec<ContractEvent>>(&json_events).unwrap()
94        );
95
96        let empty_events: Vec<ContractEvent> = vec![];
97        let empty_json_events = serde_json::to_string(&empty_events).unwrap();
98        assert_eq!(
99            empty_events,
100            serde_json::from_str::<Vec<ContractEvent>>(&empty_json_events)
101                .unwrap()
102        );
103    }
104}