1use std::cell::RefCell;
22use std::collections::VecDeque;
23use codec::{Decode, Encode, Codec};
24use tetsy_hash_db::Hasher;
25use num_traits::Zero;
26use tet_core::storage::PrefixedStorageKey;
27use tp_trie::Recorder;
28use crate::changes_trie::{AnchorBlockId, ConfigurationRange, RootsStorage, Storage, BlockNumber};
29use crate::changes_trie::input::{DigestIndex, ExtrinsicIndex, DigestIndexValue, ExtrinsicIndexValue};
30use crate::changes_trie::storage::{TrieBackendAdapter, InMemoryStorage};
31use crate::changes_trie::input::ChildIndex;
32use crate::changes_trie::surface_iterator::{surface_iterator, SurfaceIterator};
33use crate::proving_backend::ProvingBackendRecorder;
34use crate::trie_backend_essence::{TrieBackendEssence};
35
36pub fn key_changes<'a, H: Hasher, Number: BlockNumber>(
40 config: ConfigurationRange<'a, Number>,
41 storage: &'a dyn Storage<H, Number>,
42 begin: Number,
43 end: &'a AnchorBlockId<H::Out, Number>,
44 max: Number,
45 storage_key: Option<&'a PrefixedStorageKey>,
46 key: &'a [u8],
47) -> Result<DrilldownIterator<'a, H, Number>, String> {
48 let max = std::cmp::min(max, end.number.clone());
50
51 Ok(DrilldownIterator {
52 essence: DrilldownIteratorEssence {
53 storage_key,
54 key,
55 roots_storage: storage.as_roots_storage(),
56 storage,
57 begin: begin.clone(),
58 end,
59 config: config.clone(),
60 surface: surface_iterator(
61 config,
62 max,
63 begin,
64 end.number.clone(),
65 )?,
66
67 extrinsics: Default::default(),
68 blocks: Default::default(),
69
70 _hasher: ::std::marker::PhantomData::<H>::default(),
71 },
72 })
73}
74
75
76pub fn key_changes_proof<'a, H: Hasher, Number: BlockNumber>(
79 config: ConfigurationRange<'a, Number>,
80 storage: &dyn Storage<H, Number>,
81 begin: Number,
82 end: &AnchorBlockId<H::Out, Number>,
83 max: Number,
84 storage_key: Option<&PrefixedStorageKey>,
85 key: &[u8],
86) -> Result<Vec<Vec<u8>>, String> where H::Out: Codec {
87 let max = std::cmp::min(max, end.number.clone());
89
90 let mut iter = ProvingDrilldownIterator {
91 essence: DrilldownIteratorEssence {
92 storage_key,
93 key,
94 roots_storage: storage.as_roots_storage(),
95 storage,
96 begin: begin.clone(),
97 end,
98 config: config.clone(),
99 surface: surface_iterator(
100 config,
101 max,
102 begin,
103 end.number.clone(),
104 )?,
105
106 extrinsics: Default::default(),
107 blocks: Default::default(),
108
109 _hasher: ::std::marker::PhantomData::<H>::default(),
110 },
111 proof_recorder: Default::default(),
112 };
113
114 while let Some(item) = iter.next() {
116 item?;
117 }
118
119 Ok(iter.extract_proof())
120}
121
122pub fn key_changes_proof_check<'a, H: Hasher, Number: BlockNumber>(
126 config: ConfigurationRange<'a, Number>,
127 roots_storage: &dyn RootsStorage<H, Number>,
128 proof: Vec<Vec<u8>>,
129 begin: Number,
130 end: &AnchorBlockId<H::Out, Number>,
131 max: Number,
132 storage_key: Option<&PrefixedStorageKey>,
133 key: &[u8]
134) -> Result<Vec<(Number, u32)>, String> where H::Out: Encode {
135 key_changes_proof_check_with_db(
136 config,
137 roots_storage,
138 &InMemoryStorage::with_proof(proof),
139 begin,
140 end,
141 max,
142 storage_key,
143 key,
144 )
145}
146
147pub fn key_changes_proof_check_with_db<'a, H: Hasher, Number: BlockNumber>(
149 config: ConfigurationRange<'a, Number>,
150 roots_storage: &dyn RootsStorage<H, Number>,
151 proof_db: &InMemoryStorage<H, Number>,
152 begin: Number,
153 end: &AnchorBlockId<H::Out, Number>,
154 max: Number,
155 storage_key: Option<&PrefixedStorageKey>,
156 key: &[u8]
157) -> Result<Vec<(Number, u32)>, String> where H::Out: Encode {
158 let max = std::cmp::min(max, end.number.clone());
160
161 DrilldownIterator {
162 essence: DrilldownIteratorEssence {
163 storage_key,
164 key,
165 roots_storage,
166 storage: proof_db,
167 begin: begin.clone(),
168 end,
169 config: config.clone(),
170 surface: surface_iterator(
171 config,
172 max,
173 begin,
174 end.number.clone(),
175 )?,
176
177 extrinsics: Default::default(),
178 blocks: Default::default(),
179
180 _hasher: ::std::marker::PhantomData::<H>::default(),
181 },
182 }.collect()
183}
184
185pub struct DrilldownIteratorEssence<'a, H, Number>
188 where
189 H: Hasher,
190 Number: BlockNumber,
191 H::Out: 'a,
192{
193 storage_key: Option<&'a PrefixedStorageKey>,
194 key: &'a [u8],
195 roots_storage: &'a dyn RootsStorage<H, Number>,
196 storage: &'a dyn Storage<H, Number>,
197 begin: Number,
198 end: &'a AnchorBlockId<H::Out, Number>,
199 config: ConfigurationRange<'a, Number>,
200 surface: SurfaceIterator<'a, Number>,
201
202 extrinsics: VecDeque<(Number, u32)>,
203 blocks: VecDeque<(Number, Option<u32>)>,
204
205 _hasher: ::std::marker::PhantomData<H>,
206}
207
208impl<'a, H, Number> DrilldownIteratorEssence<'a, H, Number>
209 where
210 H: Hasher,
211 Number: BlockNumber,
212 H::Out: 'a,
213{
214 pub fn next<F>(&mut self, trie_reader: F) -> Option<Result<(Number, u32), String>>
215 where
216 F: FnMut(&dyn Storage<H, Number>, H::Out, &[u8]) -> Result<Option<Vec<u8>>, String>,
217 {
218 match self.do_next(trie_reader) {
219 Ok(Some(res)) => Some(Ok(res)),
220 Ok(None) => None,
221 Err(err) => Some(Err(err)),
222 }
223 }
224
225 fn do_next<F>(&mut self, mut trie_reader: F) -> Result<Option<(Number, u32)>, String>
226 where
227 F: FnMut(&dyn Storage<H, Number>, H::Out, &[u8]) -> Result<Option<Vec<u8>>, String>,
228 {
229 loop {
230 if let Some((block, extrinsic)) = self.extrinsics.pop_front() {
231 return Ok(Some((block, extrinsic)));
232 }
233
234 if let Some((block, level)) = self.blocks.pop_front() {
235 let trie_root = self.roots_storage.root(&self.end, block.clone())?
239 .ok_or_else(|| format!("Changes trie root for block {} is not found", block.clone()))?;
240 let trie_root = if let Some(storage_key) = self.storage_key {
241 let child_key = ChildIndex {
242 block: block.clone(),
243 storage_key: storage_key.clone(),
244 }.encode();
245 if let Some(trie_root) = trie_reader(self.storage, trie_root, &child_key)?
246 .and_then(|v| <Vec<u8>>::decode(&mut &v[..]).ok())
247 .map(|v| {
248 let mut hash = H::Out::default();
249 hash.as_mut().copy_from_slice(&v[..]);
250 hash
251 }) {
252 trie_root
253 } else {
254 continue;
255 }
256 } else {
257 trie_root
258 };
259
260 debug_assert!(block >= self.begin, "We shall not touch digests earlier than a range' begin");
264 if block <= self.end.number {
265 let extrinsics_key = ExtrinsicIndex { block: block.clone(), key: self.key.to_vec() }.encode();
266 let extrinsics = trie_reader(self.storage, trie_root, &extrinsics_key);
267 if let Some(extrinsics) = extrinsics? {
268 if let Ok(extrinsics) = ExtrinsicIndexValue::decode(&mut &extrinsics[..]) {
269 self.extrinsics.extend(extrinsics.into_iter().rev().map(|e| (block.clone(), e)));
270 }
271 }
272 }
273
274 let blocks_key = DigestIndex { block: block.clone(), key: self.key.to_vec() }.encode();
275 let blocks = trie_reader(self.storage, trie_root, &blocks_key);
276 if let Some(blocks) = blocks? {
277 if let Ok(blocks) = <DigestIndexValue<Number>>::decode(&mut &blocks[..]) {
278 let begin = self.begin.clone();
281 let end = self.end.number.clone();
282 let config = self.config.clone();
283 self.blocks.extend(blocks.into_iter()
284 .rev()
285 .filter(|b| level.map(|level| level > 1).unwrap_or(true) || (*b >= begin && *b <= end))
286 .map(|b| {
287 let prev_level = level
288 .map(|level| Some(level - 1))
289 .unwrap_or_else(||
290 Some(config.config.digest_level_at_block(config.zero.clone(), b.clone())
291 .map(|(level, _, _)| level)
292 .unwrap_or_else(|| Zero::zero())));
293 (b, prev_level)
294 })
295 );
296 }
297 }
298
299 continue;
300 }
301
302 match self.surface.next() {
303 Some(Ok(block)) => self.blocks.push_back(block),
304 Some(Err(err)) => return Err(err),
305 None => return Ok(None),
306 }
307 }
308 }
309}
310
311pub struct DrilldownIterator<'a, H, Number>
313 where
314 Number: BlockNumber,
315 H: Hasher,
316 H::Out: 'a,
317{
318 essence: DrilldownIteratorEssence<'a, H, Number>,
319}
320
321impl<'a, H: Hasher, Number: BlockNumber> Iterator for DrilldownIterator<'a, H, Number>
322 where H::Out: Encode
323{
324 type Item = Result<(Number, u32), String>;
325
326 fn next(&mut self) -> Option<Self::Item> {
327 self.essence.next(|storage, root, key|
328 TrieBackendEssence::<_, H>::new(TrieBackendAdapter::new(storage), root).storage(key))
329 }
330}
331
332struct ProvingDrilldownIterator<'a, H, Number>
334 where
335 Number: BlockNumber,
336 H: Hasher,
337 H::Out: 'a,
338{
339 essence: DrilldownIteratorEssence<'a, H, Number>,
340 proof_recorder: RefCell<Recorder<H::Out>>,
341}
342
343impl<'a, H, Number> ProvingDrilldownIterator<'a, H, Number>
344 where
345 Number: BlockNumber,
346 H: Hasher,
347 H::Out: 'a,
348{
349 pub fn extract_proof(self) -> Vec<Vec<u8>> {
352 self.proof_recorder.into_inner().drain()
353 .into_iter()
354 .map(|n| n.data.to_vec())
355 .collect()
356 }
357}
358
359impl<'a, H, Number> Iterator for ProvingDrilldownIterator<'a, H, Number>
360 where
361 Number: BlockNumber,
362 H: Hasher,
363 H::Out: 'a + Codec,
364{
365 type Item = Result<(Number, u32), String>;
366
367 fn next(&mut self) -> Option<Self::Item> {
368 let proof_recorder = &mut *self.proof_recorder.try_borrow_mut()
369 .expect("only fails when already borrowed; storage() is non-reentrant; qed");
370 self.essence.next(|storage, root, key|
371 ProvingBackendRecorder::<_, H> {
372 backend: &TrieBackendEssence::new(TrieBackendAdapter::new(storage), root),
373 proof_recorder,
374 }.storage(key))
375 }
376}
377
378#[cfg(test)]
379mod tests {
380 use std::iter::FromIterator;
381 use crate::changes_trie::Configuration;
382 use crate::changes_trie::input::InputPair;
383 use crate::changes_trie::storage::InMemoryStorage;
384 use tp_runtime::traits::BlakeTwo256;
385 use super::*;
386
387 fn child_key() -> PrefixedStorageKey {
388 let child_info = tet_core::storage::ChildInfo::new_default(&b"1"[..]);
389 child_info.prefixed_storage_key()
390 }
391
392 fn prepare_for_drilldown() -> (Configuration, InMemoryStorage<BlakeTwo256, u64>) {
393 let config = Configuration { digest_interval: 4, digest_levels: 2 };
394 let backend = InMemoryStorage::with_inputs(vec![
395 (1, vec![
397 ]),
398 (2, vec![
399 ]),
400 (3, vec![
401 InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 3, key: vec![42] }, vec![0]),
402 ]),
403 (4, vec![
404 InputPair::DigestIndex(DigestIndex { block: 4, key: vec![42] }, vec![3]),
405 ]),
406 (5, vec![]),
408 (6, vec![
409 InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 6, key: vec![42] }, vec![3]),
410 ]),
411 (7, vec![]),
412 (8, vec![
413 InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 8, key: vec![42] }, vec![1, 2]),
414 InputPair::DigestIndex(DigestIndex { block: 8, key: vec![42] }, vec![6]),
415 ]),
416 (9, vec![]),
418 (10, vec![]),
419 (11, vec![]),
420 (12, vec![]),
421 (13, vec![]),
423 (14, vec![]),
424 (15, vec![]),
425 (16, vec![
426 InputPair::DigestIndex(DigestIndex { block: 16, key: vec![42] }, vec![4, 8]),
427 ]),
428 ], vec![(child_key(), vec![
429 (1, vec![
430 InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 1, key: vec![42] }, vec![0]),
431 ]),
432 (2, vec![
433 InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 2, key: vec![42] }, vec![3]),
434 ]),
435 (16, vec![
436 InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 16, key: vec![42] }, vec![5]),
437
438 InputPair::DigestIndex(DigestIndex { block: 16, key: vec![42] }, vec![2]),
439 ]),
440 ]),
441 ]);
442
443 (config, backend)
444 }
445
446 fn configuration_range<'a>(config: &'a Configuration, zero: u64) -> ConfigurationRange<'a, u64> {
447 ConfigurationRange {
448 config,
449 zero,
450 end: None,
451 }
452 }
453
454 #[test]
455 fn drilldown_iterator_works() {
456 let (config, storage) = prepare_for_drilldown();
457 let drilldown_result = key_changes::<BlakeTwo256, u64>(
458 configuration_range(&config, 0),
459 &storage,
460 1,
461 &AnchorBlockId { hash: Default::default(), number: 16 },
462 16,
463 None,
464 &[42],
465 ).and_then(Result::from_iter);
466 assert_eq!(drilldown_result, Ok(vec![(8, 2), (8, 1), (6, 3), (3, 0)]));
467
468 let drilldown_result = key_changes::<BlakeTwo256, u64>(
469 configuration_range(&config, 0),
470 &storage,
471 1,
472 &AnchorBlockId { hash: Default::default(), number: 2 },
473 4,
474 None,
475 &[42],
476 ).and_then(Result::from_iter);
477 assert_eq!(drilldown_result, Ok(vec![]));
478
479 let drilldown_result = key_changes::<BlakeTwo256, u64>(
480 configuration_range(&config, 0),
481 &storage,
482 1,
483 &AnchorBlockId { hash: Default::default(), number: 3 },
484 4,
485 None,
486 &[42],
487 ).and_then(Result::from_iter);
488 assert_eq!(drilldown_result, Ok(vec![(3, 0)]));
489
490 let drilldown_result = key_changes::<BlakeTwo256, u64>(
491 configuration_range(&config, 0),
492 &storage,
493 1,
494 &AnchorBlockId { hash: Default::default(), number: 7 },
495 7,
496 None,
497 &[42],
498 ).and_then(Result::from_iter);
499 assert_eq!(drilldown_result, Ok(vec![(6, 3), (3, 0)]));
500
501 let drilldown_result = key_changes::<BlakeTwo256, u64>(
502 configuration_range(&config, 0),
503 &storage,
504 7,
505 &AnchorBlockId { hash: Default::default(), number: 8 },
506 8,
507 None,
508 &[42],
509 ).and_then(Result::from_iter);
510 assert_eq!(drilldown_result, Ok(vec![(8, 2), (8, 1)]));
511
512 let drilldown_result = key_changes::<BlakeTwo256, u64>(
513 configuration_range(&config, 0),
514 &storage,
515 5,
516 &AnchorBlockId { hash: Default::default(), number: 7 },
517 8,
518 None,
519 &[42],
520 ).and_then(Result::from_iter);
521 assert_eq!(drilldown_result, Ok(vec![(6, 3)]));
522 }
523
524 #[test]
525 fn drilldown_iterator_fails_when_storage_fails() {
526 let (config, storage) = prepare_for_drilldown();
527 storage.clear_storage();
528
529 assert!(key_changes::<BlakeTwo256, u64>(
530 configuration_range(&config, 0),
531 &storage,
532 1,
533 &AnchorBlockId { hash: Default::default(), number: 100 },
534 1000,
535 None,
536 &[42],
537 ).and_then(|i| i.collect::<Result<Vec<_>, _>>()).is_err());
538
539 assert!(key_changes::<BlakeTwo256, u64>(
540 configuration_range(&config, 0),
541 &storage,
542 1,
543 &AnchorBlockId { hash: Default::default(), number: 100 },
544 1000,
545 Some(&child_key()),
546 &[42],
547 ).and_then(|i| i.collect::<Result<Vec<_>, _>>()).is_err());
548 }
549
550 #[test]
551 fn drilldown_iterator_fails_when_range_is_invalid() {
552 let (config, storage) = prepare_for_drilldown();
553 assert!(key_changes::<BlakeTwo256, u64>(
554 configuration_range(&config, 0),
555 &storage,
556 1,
557 &AnchorBlockId { hash: Default::default(), number: 100 },
558 50,
559 None,
560 &[42],
561 ).is_err());
562 assert!(key_changes::<BlakeTwo256, u64>(
563 configuration_range(&config, 0),
564 &storage,
565 20,
566 &AnchorBlockId { hash: Default::default(), number: 10 },
567 100,
568 None,
569 &[42],
570 ).is_err());
571 }
572
573
574 #[test]
575 fn proving_drilldown_iterator_works() {
576 let (remote_config, remote_storage) = prepare_for_drilldown();
580 let remote_proof = key_changes_proof::<BlakeTwo256, u64>(
581 configuration_range(&remote_config, 0), &remote_storage, 1,
582 &AnchorBlockId { hash: Default::default(), number: 16 }, 16, None, &[42]).unwrap();
583
584 let (remote_config, remote_storage) = prepare_for_drilldown();
585 let remote_proof_child = key_changes_proof::<BlakeTwo256, u64>(
586 configuration_range(&remote_config, 0), &remote_storage, 1,
587 &AnchorBlockId { hash: Default::default(), number: 16 }, 16, Some(&child_key()), &[42]).unwrap();
588
589 let (local_config, local_storage) = prepare_for_drilldown();
593 local_storage.clear_storage();
594 let local_result = key_changes_proof_check::<BlakeTwo256, u64>(
595 configuration_range(&local_config, 0), &local_storage, remote_proof, 1,
596 &AnchorBlockId { hash: Default::default(), number: 16 }, 16, None, &[42]);
597
598 let (local_config, local_storage) = prepare_for_drilldown();
599 local_storage.clear_storage();
600 let local_result_child = key_changes_proof_check::<BlakeTwo256, u64>(
601 configuration_range(&local_config, 0), &local_storage, remote_proof_child, 1,
602 &AnchorBlockId { hash: Default::default(), number: 16 }, 16, Some(&child_key()), &[42]);
603
604 assert_eq!(local_result, Ok(vec![(8, 2), (8, 1), (6, 3), (3, 0)]));
606 assert_eq!(local_result_child, Ok(vec![(16, 5), (2, 3)]));
607 }
608
609 #[test]
610 fn drilldown_iterator_works_with_skewed_digest() {
611 let config = Configuration { digest_interval: 4, digest_levels: 3 };
612 let mut config_range = configuration_range(&config, 0);
613 config_range.end = Some(91);
614
615 let mut input = (1u64..92u64).map(|b| (b, vec![])).collect::<Vec<_>>();
622 input[63 - 1].1.push(InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 63, key: vec![42] }, vec![0]));
624 input[64 - 1].1.push(InputPair::DigestIndex(DigestIndex { block: 64, key: vec![42] }, vec![63]));
625 input[79 - 1].1.push(InputPair::ExtrinsicIndex(ExtrinsicIndex { block: 79, key: vec![42] }, vec![1]));
627 input[80 - 1].1.push(InputPair::DigestIndex(DigestIndex { block: 80, key: vec![42] }, vec![79]));
628 input[91 - 1].1.push(InputPair::DigestIndex(DigestIndex { block: 91, key: vec![42] }, vec![80]));
629 let storage = InMemoryStorage::with_inputs(input, vec![]);
630
631 let drilldown_result = key_changes::<BlakeTwo256, u64>(
632 config_range,
633 &storage,
634 1,
635 &AnchorBlockId { hash: Default::default(), number: 91 },
636 100_000u64,
637 None,
638 &[42],
639 ).and_then(Result::from_iter);
640 assert_eq!(drilldown_result, Ok(vec![(79, 1), (63, 0)]));
641 }
642}