1use crate::{updates::TrieUpdatesSorted, HashedPostStateSorted};
7use alloc::sync::Arc;
8use core::fmt;
9use reth_primitives_traits::sync::OnceLock;
10
11#[derive(Clone, Debug, Default, PartialEq, Eq)]
16#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
17pub struct SortedTrieData {
18 pub hashed_state: Arc<HashedPostStateSorted>,
20 pub trie_updates: Arc<TrieUpdatesSorted>,
22}
23
24impl SortedTrieData {
25 pub const fn new(
27 hashed_state: Arc<HashedPostStateSorted>,
28 trie_updates: Arc<TrieUpdatesSorted>,
29 ) -> Self {
30 Self { hashed_state, trie_updates }
31 }
32}
33
34pub struct LazyTrieData {
45 data: Arc<OnceLock<SortedTrieData>>,
47 compute: Option<Arc<dyn Fn() -> SortedTrieData + Send + Sync>>,
49}
50
51impl Clone for LazyTrieData {
52 fn clone(&self) -> Self {
53 Self { data: Arc::clone(&self.data), compute: self.compute.clone() }
54 }
55}
56
57impl fmt::Debug for LazyTrieData {
58 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
59 f.debug_struct("LazyTrieData")
60 .field("data", &if self.data.get().is_some() { "initialized" } else { "pending" })
61 .finish()
62 }
63}
64
65impl PartialEq for LazyTrieData {
66 fn eq(&self, other: &Self) -> bool {
67 self.get() == other.get()
68 }
69}
70
71impl Eq for LazyTrieData {}
72
73impl LazyTrieData {
74 pub fn ready(
76 hashed_state: Arc<HashedPostStateSorted>,
77 trie_updates: Arc<TrieUpdatesSorted>,
78 ) -> Self {
79 let data = OnceLock::new();
80 let _ = data.set(SortedTrieData::new(hashed_state, trie_updates));
81 Self { data: Arc::new(data), compute: None }
82 }
83
84 pub fn from_sorted(sorted: SortedTrieData) -> Self {
86 let data = OnceLock::new();
87 let _ = data.set(sorted);
88 Self { data: Arc::new(data), compute: None }
89 }
90
91 pub fn deferred(compute: impl Fn() -> SortedTrieData + Send + Sync + 'static) -> Self {
96 Self { data: Arc::new(OnceLock::new()), compute: Some(Arc::new(compute)) }
97 }
98
99 pub fn get(&self) -> &SortedTrieData {
105 self.data.get_or_init(|| {
106 self.compute.as_ref().expect("LazyTrieData::get called before initialization")()
107 })
108 }
109
110 pub fn hashed_state(&self) -> Arc<HashedPostStateSorted> {
114 Arc::clone(&self.get().hashed_state)
115 }
116
117 pub fn trie_updates(&self) -> Arc<TrieUpdatesSorted> {
121 Arc::clone(&self.get().trie_updates)
122 }
123
124 pub fn sorted_trie_data(&self) -> SortedTrieData {
128 self.get().clone()
129 }
130}
131
132#[cfg(feature = "serde")]
133impl serde::Serialize for LazyTrieData {
134 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
135 where
136 S: serde::Serializer,
137 {
138 self.get().serialize(serializer)
139 }
140}
141
142#[cfg(feature = "serde")]
143impl<'de> serde::Deserialize<'de> for LazyTrieData {
144 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
145 where
146 D: serde::Deserializer<'de>,
147 {
148 let data = SortedTrieData::deserialize(deserializer)?;
149 Ok(Self::from_sorted(data))
150 }
151}
152
153#[cfg(test)]
154mod tests {
155 use super::*;
156
157 #[test]
158 fn test_lazy_ready_is_initialized() {
159 let lazy = LazyTrieData::ready(
160 Arc::new(HashedPostStateSorted::default()),
161 Arc::new(TrieUpdatesSorted::default()),
162 );
163 let _ = lazy.hashed_state();
164 let _ = lazy.trie_updates();
165 }
166
167 #[test]
168 fn test_lazy_clone_shares_state() {
169 let lazy1 = LazyTrieData::ready(
170 Arc::new(HashedPostStateSorted::default()),
171 Arc::new(TrieUpdatesSorted::default()),
172 );
173 let lazy2 = lazy1.clone();
174
175 assert!(Arc::ptr_eq(&lazy1.hashed_state(), &lazy2.hashed_state()));
177 assert!(Arc::ptr_eq(&lazy1.trie_updates(), &lazy2.trie_updates()));
178 }
179
180 #[test]
181 fn test_lazy_deferred() {
182 let lazy = LazyTrieData::deferred(SortedTrieData::default);
183 assert!(lazy.hashed_state().is_empty());
184 assert!(lazy.trie_updates().is_empty());
185 }
186
187 #[test]
188 fn test_lazy_from_sorted() {
189 let sorted = SortedTrieData::default();
190 let lazy = LazyTrieData::from_sorted(sorted);
191 assert!(lazy.hashed_state().is_empty());
192 assert!(lazy.trie_updates().is_empty());
193 }
194}