1use crate::internal_prelude::*;
2use radix_rust::rust::{iter::*, mem};
3use radix_substate_store_interface::interface::*;
4
5#[derive(Clone, Debug)]
6pub struct RuntimeSubstate {
7 pub value: IndexedScryptoValue,
8}
9
10impl RuntimeSubstate {
11 pub fn new(value: IndexedScryptoValue) -> Self {
12 Self { value }
13 }
14}
15
16#[derive(Clone, Debug)]
17pub enum ReadOnly {
18 NonExistent,
19 Existent(RuntimeSubstate),
20}
21
22#[derive(Clone, Debug)]
23pub enum Write {
24 Update(RuntimeSubstate),
25 Delete,
26}
27
28impl Write {
29 pub fn into_value(self) -> Option<IndexedScryptoValue> {
30 match self {
31 Write::Update(substate) => Some(substate.value),
32 Write::Delete => None,
33 }
34 }
35}
36
37#[derive(Clone, Debug)]
38pub struct TrackedSubstate {
39 pub substate_key: SubstateKey,
40 pub substate_value: TrackedSubstateValue,
41}
42
43#[derive(Clone, Debug)]
45pub enum TrackedSubstateValue {
46 New(RuntimeSubstate),
47 ReadOnly(ReadOnly),
48 ReadExistAndWrite(IndexedScryptoValue, Write),
49 ReadNonExistAndWrite(RuntimeSubstate),
50 WriteOnly(Write),
51 Garbage,
52}
53
54impl TrackedSubstate {
55 pub fn size(&self) -> usize {
56 self.substate_value.size()
58 }
59}
60
61impl TrackedSubstateValue {
62 pub fn size(&self) -> usize {
63 match self {
64 TrackedSubstateValue::New(x) => x.value.len(),
65 TrackedSubstateValue::ReadOnly(r) => match r {
66 ReadOnly::NonExistent => 0,
67 ReadOnly::Existent(x) => x.value.len(),
68 },
69 TrackedSubstateValue::ReadExistAndWrite(e, w) => {
70 e.len()
71 + match w {
72 Write::Update(x) => x.value.len(),
73 Write::Delete => 0,
74 }
75 }
76 TrackedSubstateValue::ReadNonExistAndWrite(x) => x.value.len(),
77 TrackedSubstateValue::WriteOnly(w) => match w {
78 Write::Update(x) => x.value.len(),
79 Write::Delete => 0,
80 },
81 TrackedSubstateValue::Garbage => 0,
82 }
83 }
84
85 pub fn get_runtime_substate_mut(&mut self) -> Option<&mut RuntimeSubstate> {
86 match self {
87 TrackedSubstateValue::New(substate)
88 | TrackedSubstateValue::WriteOnly(Write::Update(substate))
89 | TrackedSubstateValue::ReadOnly(ReadOnly::Existent(substate))
90 | TrackedSubstateValue::ReadExistAndWrite(_, Write::Update(substate))
91 | TrackedSubstateValue::ReadNonExistAndWrite(substate) => Some(substate),
92
93 TrackedSubstateValue::WriteOnly(Write::Delete)
94 | TrackedSubstateValue::ReadExistAndWrite(_, Write::Delete)
95 | TrackedSubstateValue::ReadOnly(ReadOnly::NonExistent)
96 | TrackedSubstateValue::Garbage => None,
97 }
98 }
99
100 pub fn get(&self) -> Option<&IndexedScryptoValue> {
101 match self {
102 TrackedSubstateValue::New(substate)
103 | TrackedSubstateValue::WriteOnly(Write::Update(substate))
104 | TrackedSubstateValue::ReadOnly(ReadOnly::Existent(substate))
105 | TrackedSubstateValue::ReadExistAndWrite(_, Write::Update(substate))
106 | TrackedSubstateValue::ReadNonExistAndWrite(substate) => Some(&substate.value),
107 TrackedSubstateValue::WriteOnly(Write::Delete)
108 | TrackedSubstateValue::ReadExistAndWrite(_, Write::Delete)
109 | TrackedSubstateValue::ReadOnly(ReadOnly::NonExistent)
110 | TrackedSubstateValue::Garbage => None,
111 }
112 }
113
114 pub fn set(&mut self, value: IndexedScryptoValue) {
115 match self {
116 TrackedSubstateValue::Garbage => {
117 *self = TrackedSubstateValue::WriteOnly(Write::Update(RuntimeSubstate::new(value)));
118 }
119 TrackedSubstateValue::New(substate)
120 | TrackedSubstateValue::WriteOnly(Write::Update(substate))
121 | TrackedSubstateValue::ReadExistAndWrite(_, Write::Update(substate))
122 | TrackedSubstateValue::ReadNonExistAndWrite(substate) => {
123 substate.value = value;
124 }
125 TrackedSubstateValue::ReadOnly(ReadOnly::NonExistent) => {
126 let new_tracked =
127 TrackedSubstateValue::ReadNonExistAndWrite(RuntimeSubstate::new(value));
128 *self = new_tracked;
129 }
130 TrackedSubstateValue::ReadOnly(ReadOnly::Existent(old)) => {
131 let new_tracked = TrackedSubstateValue::ReadExistAndWrite(
132 old.value.clone(),
133 Write::Update(RuntimeSubstate::new(value)),
134 );
135 *self = new_tracked;
136 }
137 TrackedSubstateValue::ReadExistAndWrite(_, write @ Write::Delete)
138 | TrackedSubstateValue::WriteOnly(write @ Write::Delete) => {
139 *write = Write::Update(RuntimeSubstate::new(value));
140 }
141 };
142 }
143
144 pub fn take(&mut self) -> Option<IndexedScryptoValue> {
145 match self {
146 TrackedSubstateValue::Garbage => None,
147 TrackedSubstateValue::New(..) => {
148 let old = mem::replace(self, TrackedSubstateValue::Garbage);
149 old.into_value()
150 }
151 TrackedSubstateValue::WriteOnly(_) => {
152 let old = mem::replace(self, TrackedSubstateValue::WriteOnly(Write::Delete));
153 old.into_value()
154 }
155 TrackedSubstateValue::ReadExistAndWrite(_, write) => {
156 let write = mem::replace(write, Write::Delete);
157 write.into_value()
158 }
159 TrackedSubstateValue::ReadNonExistAndWrite(..) => {
160 let old = mem::replace(self, TrackedSubstateValue::ReadOnly(ReadOnly::NonExistent));
161 old.into_value()
162 }
163 TrackedSubstateValue::ReadOnly(ReadOnly::Existent(v)) => {
164 let new_tracked =
165 TrackedSubstateValue::ReadExistAndWrite(v.value.clone(), Write::Delete);
166 let old = mem::replace(self, new_tracked);
167 old.into_value()
168 }
169 TrackedSubstateValue::ReadOnly(ReadOnly::NonExistent) => None,
170 }
171 }
172
173 fn revert_writes(&mut self) {
174 match self {
175 TrackedSubstateValue::ReadOnly(..) | TrackedSubstateValue::Garbage => {}
176 TrackedSubstateValue::New(..) | TrackedSubstateValue::WriteOnly(_) => {
177 *self = TrackedSubstateValue::Garbage;
178 }
179 TrackedSubstateValue::ReadExistAndWrite(read, _) => {
180 *self = TrackedSubstateValue::ReadOnly(ReadOnly::Existent(RuntimeSubstate::new(
181 read.clone(),
182 )));
183 }
184 TrackedSubstateValue::ReadNonExistAndWrite(..) => {
185 *self = TrackedSubstateValue::ReadOnly(ReadOnly::NonExistent);
186 }
187 }
188 }
189
190 pub fn into_value(self) -> Option<IndexedScryptoValue> {
191 match self {
192 TrackedSubstateValue::New(substate)
193 | TrackedSubstateValue::WriteOnly(Write::Update(substate))
194 | TrackedSubstateValue::ReadOnly(ReadOnly::Existent(substate))
195 | TrackedSubstateValue::ReadNonExistAndWrite(substate)
196 | TrackedSubstateValue::ReadExistAndWrite(_, Write::Update(substate)) => {
197 Some(substate.value)
198 }
199 TrackedSubstateValue::WriteOnly(Write::Delete)
200 | TrackedSubstateValue::ReadExistAndWrite(_, Write::Delete)
201 | TrackedSubstateValue::ReadOnly(ReadOnly::NonExistent)
202 | TrackedSubstateValue::Garbage => None,
203 }
204 }
205}
206
207#[derive(Debug)]
208pub struct TrackedPartition {
209 pub substates: BTreeMap<DbSortKey, TrackedSubstate>,
210 pub range_read: u32,
211}
212
213impl TrackedPartition {
214 pub fn new() -> Self {
215 Self {
216 substates: BTreeMap::new(),
217 range_read: 0,
218 }
219 }
220
221 pub fn new_with_substates(substates: BTreeMap<DbSortKey, TrackedSubstate>) -> Self {
222 Self {
223 substates,
224 range_read: 0,
225 }
226 }
227
228 pub fn revert_writes(&mut self) {
229 for substate in &mut self.substates.values_mut() {
230 substate.substate_value.revert_writes();
231 }
232 }
233}
234
235#[derive(Debug)]
236pub struct TrackedNode {
237 pub tracked_partitions: IndexMap<PartitionNumber, TrackedPartition>,
238 pub is_new: bool,
242}
243
244impl TrackedNode {
245 pub fn new(is_new: bool) -> Self {
246 Self {
247 tracked_partitions: index_map_new(),
248 is_new,
249 }
250 }
251
252 pub fn revert_writes(&mut self) {
253 for (_, tracked_partition) in &mut self.tracked_partitions {
254 tracked_partition.revert_writes();
255 }
256 }
257}
258
259pub struct IterationCountedIter<'a, E> {
260 pub iter:
261 Box<dyn Iterator<Item = Result<(DbSortKey, (SubstateKey, IndexedScryptoValue)), E>> + 'a>,
262 pub num_iterations: u32,
263}
264
265impl<'a, E> IterationCountedIter<'a, E> {
266 pub fn new(
267 iter: Box<
268 dyn Iterator<Item = Result<(DbSortKey, (SubstateKey, IndexedScryptoValue)), E>> + 'a,
269 >,
270 ) -> Self {
271 Self {
272 iter,
273 num_iterations: 0u32,
274 }
275 }
276}
277
278impl<'a, E> Iterator for IterationCountedIter<'a, E> {
279 type Item = Result<(DbSortKey, (SubstateKey, IndexedScryptoValue)), E>;
280
281 fn next(&mut self) -> Option<Self::Item> {
282 self.num_iterations = self.num_iterations + 1;
283 self.iter.next()
284 }
285}