fuel_core_compression/
ports.rs

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
//! Ports this service requires to function.

use fuel_core_types::{
    fuel_compression::RegistryKey,
    fuel_tx::{
        Address,
        AssetId,
        CompressedUtxoId,
        UtxoId,
        Word,
    },
    fuel_types::Nonce,
    tai64::Tai64,
};

/// Rolling cache for compression.
/// Holds the latest state which can be event sourced from the compressed blocks.
/// The changes done using this trait in a single call to `compress` or `decompress`
/// must be committed atomically, after which block height must be incremented.
pub trait TemporalRegistry<T> {
    /// Reads a value from the registry at its current height.
    fn read_registry(&self, key: &RegistryKey) -> anyhow::Result<T>;

    /// Reads timestamp of the value from the registry.
    fn read_timestamp(&self, key: &RegistryKey) -> anyhow::Result<Tai64>;

    /// Writes a value from to the registry. The timestamp is the time of the block,
    /// and it is used for key retention.
    fn write_registry(
        &mut self,
        key: &RegistryKey,
        value: &T,
        timestamp: Tai64,
    ) -> anyhow::Result<()>;

    /// Lookup registry key by the value.
    fn registry_index_lookup(&self, value: &T) -> anyhow::Result<Option<RegistryKey>>;
}

impl<D, T> TemporalRegistry<T> for &mut D
where
    D: TemporalRegistry<T>,
{
    fn read_registry(&self, key: &RegistryKey) -> anyhow::Result<T> {
        <D as TemporalRegistry<T>>::read_registry(self, key)
    }

    fn read_timestamp(&self, key: &RegistryKey) -> anyhow::Result<Tai64> {
        <D as TemporalRegistry<T>>::read_timestamp(self, key)
    }

    fn write_registry(
        &mut self,
        key: &RegistryKey,
        value: &T,
        timestamp: Tai64,
    ) -> anyhow::Result<()> {
        <D as TemporalRegistry<T>>::write_registry(self, key, value, timestamp)
    }

    fn registry_index_lookup(&self, value: &T) -> anyhow::Result<Option<RegistryKey>> {
        <D as TemporalRegistry<T>>::registry_index_lookup(self, value)
    }
}

/// Lookup for UTXO pointers used for compression.
pub trait UtxoIdToPointer {
    fn lookup(&self, utxo_id: UtxoId) -> anyhow::Result<CompressedUtxoId>;
}

impl<D> UtxoIdToPointer for &mut D
where
    D: UtxoIdToPointer,
{
    fn lookup(&self, utxo_id: UtxoId) -> anyhow::Result<CompressedUtxoId> {
        <D as UtxoIdToPointer>::lookup(self, utxo_id)
    }
}

/// Lookup for history of UTXOs and messages, used for decompression.
pub trait HistoryLookup {
    fn utxo_id(&self, c: CompressedUtxoId) -> anyhow::Result<UtxoId>;
    fn coin(&self, utxo_id: UtxoId) -> anyhow::Result<CoinInfo>;
    fn message(&self, nonce: Nonce) -> anyhow::Result<MessageInfo>;
}

/// Information about a coin.
#[derive(Debug, Clone)]
pub struct CoinInfo {
    pub owner: Address,
    pub amount: u64,
    pub asset_id: AssetId,
}

/// Information about a message.
#[derive(Debug, Clone)]
pub struct MessageInfo {
    pub sender: Address,
    pub recipient: Address,
    pub amount: Word,
    pub data: Vec<u8>,
}

/// Evictor registry to keep track of the latest used key for the type `T`.
pub trait EvictorDb<T> {
    fn get_latest_assigned_key(&self) -> anyhow::Result<Option<RegistryKey>>;
    fn set_latest_assigned_key(&mut self, key: RegistryKey) -> anyhow::Result<()>;
}

impl<D, T> EvictorDb<T> for &mut D
where
    D: EvictorDb<T>,
{
    fn get_latest_assigned_key(&self) -> anyhow::Result<Option<RegistryKey>> {
        <D as EvictorDb<T>>::get_latest_assigned_key(self)
    }

    fn set_latest_assigned_key(&mut self, key: RegistryKey) -> anyhow::Result<()> {
        <D as EvictorDb<T>>::set_latest_assigned_key(self, key)
    }
}