aleph_types/message/
store.rs

1use crate::cid::Cid;
2use crate::item_hash::ItemHash;
3use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5
6#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
7#[serde(tag = "item_type", rename_all = "lowercase")]
8pub enum StorageBackend {
9    Ipfs { item_hash: Cid },
10    Storage { item_hash: ItemHash },
11}
12
13#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
14pub struct StoreContent {
15    #[serde(flatten)]
16    item_type: StorageBackend,
17    #[serde(default)]
18    /// Size of the file. Generated by CCNs upon processing.
19    size: Option<u64>,
20    /// Generated by CCNs upon processing.
21    content_type: Option<String>,
22    #[serde(rename = "ref", default)]
23    reference: Option<String>,
24    /// Metadata of the VM.
25    metadata: Option<HashMap<String, serde_json::Value>>,
26}
27
28#[cfg(test)]
29mod tests {
30    use super::*;
31    use crate::chain::{Address, Chain, Signature};
32    use crate::channel::Channel;
33    use crate::message::base_message::{Message, MessageContentEnum};
34    use crate::message::{ContentSource, MessageType};
35    use crate::timestamp::Timestamp;
36    use assert_matches::assert_matches;
37
38    const STORE_IPFS_FIXTURE: &str = include_str!(concat!(
39        env!("CARGO_MANIFEST_DIR"),
40        "/../../fixtures/messages/store/store-ipfs.json"
41    ));
42
43    #[test]
44    fn test_deserialize_store_message() {
45        let message: Message = serde_json::from_str(STORE_IPFS_FIXTURE).unwrap();
46
47        assert_eq!(
48            message.sender,
49            Address::from("0x238224C744F4b90b4494516e074D2676ECfC6803".to_string())
50        );
51        assert_eq!(message.chain, Chain::Ethereum);
52        assert_eq!(
53                message.signature,
54                Signature::from(
55                    "0x9c87f5d659b9165be7cbd4b9f0bd5df5c66b9bb9a384a0a33b1277428be21244595a0731697035c4b085064cd3fc088bc5b3cddeb22159e7f462e6e5b5e7e8181c".to_string()
56                )
57            );
58        assert_matches!(message.message_type, MessageType::Store);
59        assert_matches!(
60            message.content_source,
61            ContentSource::Inline { item_content: _ }
62        );
63        assert_eq!(
64            &message.item_hash.to_string(),
65            "afe106f1fd70b6b806e0452cc2f9485e518143581ffd046ae19fc64af7b6bbaa"
66        );
67        assert_eq!(message.time, Timestamp::from(1761047957.74837));
68        assert_matches!(message.channel, Some(ref channel) if channel == &Channel::from("ALEPH-CLOUDSOLUTIONS".to_string()));
69
70        // Check content fields
71        assert_eq!(
72            &message.content.address,
73            &Address::from("0x238224C744F4b90b4494516e074D2676ECfC6803".to_string())
74        );
75        assert_eq!(&message.content.time, &Timestamp::from(1761047957.7483068));
76
77        // Check STORE-specific fields
78        match message.content() {
79            MessageContentEnum::Store(store) => {
80                assert_eq!(
81                    store.item_type,
82                    StorageBackend::Ipfs {
83                        item_hash: Cid::try_from("QmYULJoNGPDmoRq4WNWTDTUvJGJv1hosox8H6vVd1kCsY8")
84                            .unwrap()
85                    }
86                );
87
88                assert!(store.size.is_none());
89                assert!(store.content_type.is_none());
90                assert!(store.reference.is_none());
91                assert!(store.metadata.is_none());
92            }
93            other => {
94                panic!("Expected MessageContentEnum::Store, got {:?}", other)
95            }
96        }
97
98        // Check confirmations
99        assert!(message.confirmed());
100        assert_eq!(message.confirmations.len(), 1);
101
102        let confirmation = &message.confirmations[0];
103        assert_eq!(confirmation.chain, Chain::Ethereum);
104        assert_eq!(confirmation.height, 23626206);
105        assert_eq!(
106            confirmation.hash,
107            "0x7e73ff97d7920fcfc289a899aeac4bc2898d1482a9876bd2ac4584ae876d22be"
108        );
109        assert!(confirmation.time.is_none());
110        assert!(confirmation.publisher.is_none());
111    }
112
113    #[test]
114    fn test_deserialize_serialized_store_message() {
115        let message: Message = serde_json::from_str(STORE_IPFS_FIXTURE).unwrap();
116        let serialized_message = serde_json::to_string(&message).unwrap();
117        let deserialized_message: Message = serde_json::from_str(&serialized_message).unwrap();
118
119        assert_eq!(message, deserialized_message);
120    }
121}