Skip to main content

fuel_core_compression/
registry.rs

1use crate::ports::{
2    EvictorDb,
3    TemporalRegistry,
4};
5use fuel_core_types::{
6    fuel_compression::RegistryKey,
7    fuel_tx::{
8        Address,
9        AssetId,
10        ContractId,
11        ScriptCode,
12        input::PredicateCode,
13    },
14    tai64::Tai64,
15};
16
17macro_rules! tables {
18    ($($ident:ty: $type:ty),*) => { paste::paste! {
19        #[doc = "RegistryKey namespaces"]
20        #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize, strum_macros::EnumCount)]
21        pub enum RegistryKeyspace {
22            $(
23                [<$type>],
24            )*
25        }
26
27        #[doc = "A value for each keyspace"]
28        #[derive(Debug, Clone, PartialEq, Eq, Default)]
29        pub struct PerRegistryKeyspace<T> {
30            $(pub $ident: T,)*
31        }
32        impl<T> core::ops::Index<RegistryKeyspace> for PerRegistryKeyspace<T> {
33            type Output = T;
34
35            fn index(&self, index: RegistryKeyspace) -> &Self::Output {
36                match index {
37                    $(
38                        RegistryKeyspace::[<$type>] => &self.$ident,
39                    )*
40                }
41            }
42        }
43        impl<T> core::ops::IndexMut<RegistryKeyspace> for PerRegistryKeyspace<T> {
44            fn index_mut(&mut self, index: RegistryKeyspace) -> &mut Self::Output {
45                match index {
46                    $(
47                        RegistryKeyspace::[<$type>] => &mut self.$ident,
48                    )*
49                }
50            }
51        }
52
53        #[doc = "The set of registrations for each table, as used in the compressed block header"]
54        #[derive(Debug, Clone, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)]
55        pub struct RegistrationsPerTable {
56            $(pub $ident: Vec<(RegistryKey, $type)>,)*
57        }
58
59        pub trait TemporalRegistryAll
60        where
61            $(Self: TemporalRegistry<$type>,)*
62        {}
63
64        impl<T> TemporalRegistryAll for T
65        where
66            $(T: TemporalRegistry<$type>,)*
67        {}
68
69        pub trait EvictorDbAll
70        where
71            $(Self: EvictorDb<$type>,)*
72        {}
73
74        impl<T> EvictorDbAll for T
75        where
76            $(T: EvictorDb<$type>,)*
77        {}
78
79
80        impl RegistrationsPerTable {
81            pub fn write_to_registry<R>(&self, registry: &mut R, timestamp: Tai64) -> anyhow::Result<()>
82            where
83                R: TemporalRegistryAll
84            {
85                $(
86                    for (key, value) in self.$ident.iter() {
87                        registry.write_registry(key, value, timestamp)?;
88                    }
89                )*
90
91                Ok(())
92            }
93        }
94    }};
95}
96
97tables!(
98    address: Address,
99    asset_id: AssetId,
100    contract_id: ContractId,
101    script_code: ScriptCode,
102    predicate_code: PredicateCode
103);
104
105// TODO: move inside the macro when this stabilizes: https://github.com/rust-lang/rust/pull/122808
106#[cfg(any(test, feature = "test-helpers"))]
107impl rand::prelude::Distribution<RegistryKeyspace> for rand::distributions::Standard {
108    fn sample<R: rand::Rng + ?Sized>(&self, rng: &mut R) -> RegistryKeyspace {
109        use strum::EnumCount;
110        match rng.gen_range(0..RegistryKeyspace::COUNT) {
111            0 => RegistryKeyspace::Address,
112            1 => RegistryKeyspace::AssetId,
113            2 => RegistryKeyspace::ContractId,
114            3 => RegistryKeyspace::ScriptCode,
115            4 => RegistryKeyspace::PredicateCode,
116            _ => unreachable!("New keyspace is added but not supported here"),
117        }
118    }
119}