1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
use crate::{
    database::{
        database_description::off_chain::OffChain,
        Database,
    },
    fuel_core_graphql_api::storage::messages::{
        OwnedMessageIds,
        OwnedMessageKey,
        SpentMessages,
    },
};
use fuel_core_chain_config::TableEntry;
use fuel_core_storage::{
    iter::{
        IterDirection,
        IteratorOverTable,
    },
    tables::Messages,
    Result as StorageResult,
};
use fuel_core_types::{
    entities::relayer::message::Message,
    fuel_types::{
        Address,
        Nonce,
    },
};
use itertools::Itertools;

impl Database<OffChain> {
    pub fn owned_message_ids(
        &self,
        owner: &Address,
        start_message_id: Option<Nonce>,
        direction: Option<IterDirection>,
    ) -> impl Iterator<Item = StorageResult<Nonce>> + '_ {
        let start_message_id =
            start_message_id.map(|msg_id| OwnedMessageKey::new(owner, &msg_id));
        self.iter_all_filtered::<OwnedMessageIds, _>(
            Some(*owner),
            start_message_id.as_ref(),
            direction,
        )
        .map(|res| res.map(|(key, _)| *key.nonce()))
    }

    pub fn message_is_spent(&self, id: &Nonce) -> StorageResult<bool> {
        fuel_core_storage::StorageAsRef::storage::<SpentMessages>(&self).contains_key(id)
    }
}

impl Database {
    pub fn all_messages(
        &self,
        start: Option<Nonce>,
        direction: Option<IterDirection>,
    ) -> impl Iterator<Item = StorageResult<Message>> + '_ {
        self.iter_all_by_start::<Messages>(start.as_ref(), direction)
            .map(|res| res.map(|(_, message)| message))
    }

    pub fn iter_messages(
        &self,
    ) -> impl Iterator<Item = StorageResult<TableEntry<Messages>>> + '_ {
        self.iter_all_by_start::<Messages>(None, None)
            .map_ok(|(key, value)| TableEntry { key, value })
    }

    pub fn message_exists(&self, id: &Nonce) -> StorageResult<bool> {
        fuel_core_storage::StorageAsRef::storage::<Messages>(&self).contains_key(id)
    }
}