fuel_core_compression/
registry.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
use crate::ports::{
    EvictorDb,
    TemporalRegistry,
};
use fuel_core_types::{
    fuel_compression::RegistryKey,
    fuel_tx::{
        input::PredicateCode,
        Address,
        AssetId,
        ContractId,
        ScriptCode,
    },
    tai64::Tai64,
};

macro_rules! tables {
    ($($ident:ty: $type:ty),*) => { paste::paste! {
        #[doc = "RegistryKey namespaces"]
        #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize, strum_macros::EnumCount)]
        pub enum RegistryKeyspace {
            $(
                [<$type>],
            )*
        }

        #[doc = "A value for each keyspace"]
        #[derive(Debug, Clone, PartialEq, Eq, Default)]
        pub struct PerRegistryKeyspace<T> {
            $(pub $ident: T,)*
        }
        impl<T> core::ops::Index<RegistryKeyspace> for PerRegistryKeyspace<T> {
            type Output = T;

            fn index(&self, index: RegistryKeyspace) -> &Self::Output {
                match index {
                    $(
                        RegistryKeyspace::[<$type>] => &self.$ident,
                    )*
                }
            }
        }
        impl<T> core::ops::IndexMut<RegistryKeyspace> for PerRegistryKeyspace<T> {
            fn index_mut(&mut self, index: RegistryKeyspace) -> &mut Self::Output {
                match index {
                    $(
                        RegistryKeyspace::[<$type>] => &mut self.$ident,
                    )*
                }
            }
        }

        #[doc = "The set of registrations for each table, as used in the compressed block header"]
        #[derive(Debug, Clone, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)]
        pub struct RegistrationsPerTable {
            $(pub $ident: Vec<(RegistryKey, $type)>,)*
        }

        pub trait TemporalRegistryAll
        where
            $(Self: TemporalRegistry<$type>,)*
        {}

        impl<T> TemporalRegistryAll for T
        where
            $(T: TemporalRegistry<$type>,)*
        {}

        pub trait EvictorDbAll
        where
            $(Self: EvictorDb<$type>,)*
        {}

        impl<T> EvictorDbAll for T
        where
            $(T: EvictorDb<$type>,)*
        {}


        impl RegistrationsPerTable {
            pub(crate) fn write_to_registry<R>(&self, registry: &mut R, timestamp: Tai64) -> anyhow::Result<()>
            where
                R: TemporalRegistryAll
            {
                $(
                    for (key, value) in self.$ident.iter() {
                        registry.write_registry(key, value, timestamp)?;
                    }
                )*

                Ok(())
            }
        }
    }};
}

tables!(
    address: Address,
    asset_id: AssetId,
    contract_id: ContractId,
    script_code: ScriptCode,
    predicate_code: PredicateCode
);

// TODO: move inside the macro when this stabilizes: https://github.com/rust-lang/rust/pull/122808
#[cfg(any(test, feature = "test-helpers"))]
impl rand::prelude::Distribution<RegistryKeyspace> for rand::distributions::Standard {
    fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> RegistryKeyspace {
        use strum::EnumCount;
        match rng.gen_range(0..RegistryKeyspace::COUNT) {
            0 => RegistryKeyspace::Address,
            1 => RegistryKeyspace::AssetId,
            2 => RegistryKeyspace::ContractId,
            3 => RegistryKeyspace::ScriptCode,
            4 => RegistryKeyspace::PredicateCode,
            _ => unreachable!("New keyspace is added but not supported here"),
        }
    }
}