1use crate::{
4 Error,
5 engine::Engine,
6 model::{ArchiveStatus, ChainPoint, Omission},
7};
8use std::{
9 sync::atomic::{AtomicBool, Ordering},
10 time::{Duration, Instant},
11};
12
13pub struct CatchUp {
15 pub scanned: u64,
16 pub outcome: Result<ArchiveStatus, Error>,
17}
18
19impl Engine {
20 pub fn scan_catch_up(&self, cancelled: &AtomicBool, blocks: u64, time: Duration) -> CatchUp {
25 let deadline = Instant::now() + time;
26 let mut scanned = 0;
27 let mut last = match self.status() {
28 Ok(status) => status,
29 Err(error) => {
30 return CatchUp {
31 scanned,
32 outcome: Err(error),
33 };
34 }
35 };
36 while scanned < blocks && Instant::now() < deadline && !cancelled.load(Ordering::Acquire) {
37 match self.scan_next_until(cancelled) {
38 Ok(next) if next.scanned_blocks == last.scanned_blocks => {
39 last = next;
40 break;
41 }
42 Ok(next) => {
43 scanned += 1;
44 last = next;
45 }
46 Err(error) => {
47 return CatchUp {
48 scanned,
49 outcome: Err(error),
50 };
51 }
52 }
53 }
54 CatchUp {
55 scanned,
56 outcome: Ok(last),
57 }
58 }
59
60 pub fn record_peer_coverage(
67 &self,
68 peer: &str,
69 from: u64,
70 to: u64,
71 generation: u64,
72 ) -> Result<(), Error> {
73 self.archive()?
74 .record_peer_coverage(peer, from, to, generation)
75 }
76
77 pub fn peer_cursor(&self, peer: &str) -> Result<u64, Error> {
79 self.archive()?.peer_cursor(peer, 0)
80 }
81
82 pub fn peer_cursor_from(&self, peer: &str, floor: u64) -> Result<u64, Error> {
85 self.archive()?.peer_cursor(peer, floor)
86 }
87
88 pub fn peer_synced_through(&self) -> Result<Option<ChainPoint>, Error> {
89 self.archive()?.peer_synced_through()
90 }
91
92 pub fn omitting_peers(&self) -> Result<Vec<String>, Error> {
93 self.archive()?.omitting_peers()
94 }
95
96 pub fn peer_omissions(&self) -> Result<Vec<Omission>, Error> {
97 self.archive()?.peer_omissions()
98 }
99
100 pub fn peer_omissions_latest(&self, limit: u32) -> Result<Vec<Omission>, Error> {
102 self.archive()?.peer_omissions_latest(limit)
103 }
104
105 pub fn chain_peers(&self) -> Result<u64, Error> {
107 match &self.source {
108 Some(source) => source.chain_peers(),
109 None => Ok(0),
110 }
111 }
112
113 pub fn chain_target(&self) -> Option<u64> {
115 self.source
116 .as_ref()
117 .and_then(|source| source.chain_target())
118 }
119}