Skip to main content

hypercall_db/types/
validator_rsm.rs

1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Deserializer, Serialize, Serializer};
3use std::fmt;
4use std::str::FromStr;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7#[repr(i16)]
8pub enum ValidatorRsmEnvironment {
9    Development = 1,
10    Staging = 2,
11    Testnet = 3,
12    Mainnet = 4,
13}
14
15impl ValidatorRsmEnvironment {
16    pub fn as_i16(self) -> i16 {
17        self as i16
18    }
19}
20
21impl FromStr for ValidatorRsmEnvironment {
22    type Err = anyhow::Error;
23
24    fn from_str(value: &str) -> Result<Self, Self::Err> {
25        match value.trim().to_ascii_lowercase().as_str() {
26            "development" | "dev" | "local" => Ok(Self::Development),
27            "staging" | "aws-staging" | "linode-staging" => Ok(Self::Staging),
28            "testnet" => Ok(Self::Testnet),
29            "mainnet" | "production" | "prod" => Ok(Self::Mainnet),
30            other => Err(anyhow::anyhow!(
31                "unknown validator RSM environment name: {other}"
32            )),
33        }
34    }
35}
36
37impl TryFrom<i16> for ValidatorRsmEnvironment {
38    type Error = anyhow::Error;
39
40    fn try_from(value: i16) -> Result<Self, Self::Error> {
41        match value {
42            1 => Ok(Self::Development),
43            2 => Ok(Self::Staging),
44            3 => Ok(Self::Testnet),
45            4 => Ok(Self::Mainnet),
46            _ => Err(anyhow::anyhow!(
47                "unknown validator RSM environment id: {value}"
48            )),
49        }
50    }
51}
52
53impl fmt::Display for ValidatorRsmEnvironment {
54    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55        let name = match self {
56            Self::Development => "development",
57            Self::Staging => "staging",
58            Self::Testnet => "testnet",
59            Self::Mainnet => "mainnet",
60        };
61        f.write_str(name)
62    }
63}
64
65impl Serialize for ValidatorRsmEnvironment {
66    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
67    where
68        S: Serializer,
69    {
70        serializer.serialize_str(&self.to_string())
71    }
72}
73
74impl<'de> Deserialize<'de> for ValidatorRsmEnvironment {
75    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
76    where
77        D: Deserializer<'de>,
78    {
79        let value = String::deserialize(deserializer)?;
80        value.parse().map_err(serde::de::Error::custom)
81    }
82}
83
84#[derive(Debug, Clone, PartialEq, Eq)]
85pub struct ValidatorRsmRootSummary {
86    pub environment: ValidatorRsmEnvironment,
87    pub version: u64,
88    pub batch_seq: u64,
89    pub state_root: [u8; 32],
90    pub risk_root: [u8; 32],
91    pub command_mmr_root: [u8; 32],
92    pub obligation_mmr_root: [u8; 32],
93    pub intent_mmr_root: [u8; 32],
94    pub batch_root: [u8; 32],
95    pub command_range_start: u64,
96    pub command_range_end: u64,
97    pub command_count: u64,
98    pub schema_version: i32,
99    pub accepted_block_hash: [u8; 32],
100    pub created_at: DateTime<Utc>,
101}
102
103#[derive(Debug, Clone, PartialEq, Eq)]
104pub struct RsmBlockHeader {
105    pub environment: ValidatorRsmEnvironment,
106    pub height: u64,
107    pub hash: [u8; 32],
108    pub parent_hash: [u8; 32],
109    pub commands_hash: [u8; 32],
110    pub batch_root: [u8; 32],
111    pub command_count: u64,
112    pub first_command_seq: u64,
113    pub last_command_seq: u64,
114    pub signer: Option<[u8; 20]>,
115    pub signature: Option<Vec<u8>>,
116    pub created_at: DateTime<Utc>,
117}
118
119#[derive(Debug, Clone, PartialEq, Eq)]
120pub struct NewRsmBlockHeader {
121    pub environment: ValidatorRsmEnvironment,
122    pub height: u64,
123    pub hash: [u8; 32],
124    pub parent_hash: [u8; 32],
125    pub commands_hash: [u8; 32],
126    pub batch_root: [u8; 32],
127    pub command_count: u64,
128    pub first_command_seq: u64,
129    pub last_command_seq: u64,
130    pub signer: Option<[u8; 20]>,
131    pub signature: Option<Vec<u8>>,
132}
133
134#[derive(Debug, Clone, PartialEq, Eq)]
135pub struct RsmBlockView {
136    pub block: RsmBlockHeader,
137    pub root_summary: ValidatorRsmRootSummary,
138}
139
140#[derive(Debug, Clone, PartialEq, Eq)]
141pub struct RsmBlockCommand {
142    pub environment: ValidatorRsmEnvironment,
143    pub height: u64,
144    pub rsm_command_seq: u64,
145    pub command_index: u64,
146    pub engine_command_id: i64,
147    pub request_uuid: uuid::Uuid,
148    pub command_type: String,
149    pub command_data: Vec<u8>,
150    pub command_identity_hash: [u8; 32],
151    pub created_at: DateTime<Utc>,
152}
153
154#[derive(Debug, Clone, PartialEq, Eq)]
155pub struct NewRsmBlockCommand {
156    pub environment: ValidatorRsmEnvironment,
157    pub height: u64,
158    pub rsm_command_seq: u64,
159    pub command_index: u64,
160    pub engine_command_id: i64,
161    pub request_uuid: uuid::Uuid,
162    pub command_type: String,
163    pub command_data: Vec<u8>,
164    pub command_identity_hash: [u8; 32],
165}
166
167#[derive(Debug, Clone, PartialEq, Eq)]
168pub struct RsmBlockData {
169    pub block: RsmBlockView,
170    pub commands: Vec<RsmBlockCommand>,
171}
172
173#[derive(Debug, Clone, PartialEq, Eq)]
174pub struct NewValidatorRsmRootSummary {
175    pub environment: ValidatorRsmEnvironment,
176    pub version: u64,
177    pub batch_seq: u64,
178    pub state_root: [u8; 32],
179    pub risk_root: [u8; 32],
180    pub command_mmr_root: [u8; 32],
181    pub obligation_mmr_root: [u8; 32],
182    pub intent_mmr_root: [u8; 32],
183    pub batch_root: [u8; 32],
184    pub command_range_start: u64,
185    pub command_range_end: u64,
186    pub command_count: u64,
187    pub schema_version: i32,
188    pub accepted_block_hash: [u8; 32],
189}
190
191#[derive(Debug, Clone, PartialEq, Eq)]
192pub struct ValidatorRsmCurrentState {
193    pub environment: ValidatorRsmEnvironment,
194    pub current_version: u64,
195    pub updated_at: DateTime<Utc>,
196}
197
198#[cfg(test)]
199mod tests {
200    use super::*;
201
202    #[test]
203    fn validator_rsm_environment_roundtrips_known_ids() {
204        for environment in [
205            ValidatorRsmEnvironment::Development,
206            ValidatorRsmEnvironment::Staging,
207            ValidatorRsmEnvironment::Testnet,
208            ValidatorRsmEnvironment::Mainnet,
209        ] {
210            assert_eq!(
211                ValidatorRsmEnvironment::try_from(environment.as_i16()).unwrap(),
212                environment
213            );
214        }
215    }
216
217    #[test]
218    fn validator_rsm_environment_rejects_unknown_ids() {
219        assert!(ValidatorRsmEnvironment::try_from(0).is_err());
220        assert!(ValidatorRsmEnvironment::try_from(5).is_err());
221    }
222
223    #[test]
224    fn validator_rsm_environment_parses_names() {
225        assert_eq!(
226            "development".parse::<ValidatorRsmEnvironment>().unwrap(),
227            ValidatorRsmEnvironment::Development
228        );
229        assert_eq!(
230            "staging".parse::<ValidatorRsmEnvironment>().unwrap(),
231            ValidatorRsmEnvironment::Staging
232        );
233        assert!("unknown".parse::<ValidatorRsmEnvironment>().is_err());
234    }
235}