Skip to main content

urma_runtime/
publication_progress.rs

1use crate::{node::Presence, publish::PublishReport};
2use serde::{Deserialize, Serialize};
3
4#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
5#[serde(rename_all = "snake_case")]
6pub enum Target {
7    Mempool,
8    Confirmed,
9}
10
11#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
12#[serde(tag = "status", rename_all = "snake_case")]
13pub enum State {
14    Prepared,
15    Missing,
16    Mempool,
17    Confirmed,
18    SourceUnavailable { reason: String },
19}
20
21#[derive(Clone, Debug, Serialize, Deserialize)]
22pub struct Observation {
23    pub txid: String,
24    pub role: String,
25    pub state: State,
26}
27
28#[derive(Clone, Serialize)]
29pub struct Progress {
30    pub report: PublishReport,
31    pub total: usize,
32    pub observations: Vec<Observation>,
33    pub retryable: bool,
34}
35
36impl Progress {
37    pub fn reached(&self, target: Target) -> bool {
38        self.observations.len() == self.total
39            && self.observations.iter().all(|observation| match target {
40                Target::Confirmed => observation.state == State::Confirmed,
41                Target::Mempool => matches!(observation.state, State::Mempool | State::Confirmed),
42            })
43    }
44
45    pub fn summary(&self) -> String {
46        let count = |state: State| {
47            self.observations
48                .iter()
49                .filter(|row| row.state == state)
50                .count()
51        };
52        let unavailable = self
53            .observations
54            .iter()
55            .filter(|row| matches!(row.state, State::SourceUnavailable { .. }))
56            .count();
57        format!(
58            "{}/{} checked: {} confirmed, {} mempool, {} prepared/not submitted, {} missing, {} source unavailable",
59            self.observations.len(),
60            self.total,
61            count(State::Confirmed),
62            count(State::Mempool),
63            count(State::Prepared),
64            count(State::Missing),
65            unavailable
66        )
67    }
68}
69
70pub(crate) fn state(presence: &Presence, attempted: bool) -> State {
71    match presence {
72        Presence::Confirmed { .. } => State::Confirmed,
73        Presence::Mempool => State::Mempool,
74        Presence::Missing if attempted => State::Missing,
75        Presence::Missing => State::Prepared,
76    }
77}