mdp/state/
record.rs

1use std::borrow::Cow;
2
3use super::{features::FeaturesSet, status::ErStatus, version::v0::RecordV0};
4use borsh::{BorshDeserialize, BorshSerialize};
5use solana_program::pubkey::Pubkey;
6
7use crate::{consts::ER_RECORD_SEED, ID};
8
9#[derive(Debug, BorshSerialize, BorshDeserialize)]
10#[cfg_attr(not(feature = "entrypoint"), derive(PartialEq, Eq, Clone))]
11pub enum ErRecord {
12    V0(RecordV0),
13}
14
15impl ErRecord {
16    /// Computes record's PDA for the given ER node
17    pub fn pda(&self) -> (Pubkey, u8) {
18        Pubkey::find_program_address(&self.seeds(), &ID)
19    }
20
21    /// Returns an array of seeds for the record's PDA derivation
22    pub fn seeds(&self) -> [&[u8]; 2] {
23        [ER_RECORD_SEED, self.identity().as_ref()]
24    }
25
26    /// Returns identity pubkey of the given ER
27    pub fn identity(&self) -> &Pubkey {
28        match self {
29            Self::V0(r) => &r.identity,
30        }
31    }
32
33    /// Returns FQDN address for the given ER node
34    pub fn addr(&self) -> &str {
35        match self {
36            Self::V0(v) => &v.addr,
37        }
38    }
39
40    /// Returns transaction fees of given ER node
41    pub fn base_fee(&self) -> u16 {
42        match self {
43            Self::V0(v) => v.base_fee,
44        }
45    }
46
47    /// Returns supported set of features by the given ER node
48    pub fn features(&self) -> &FeaturesSet {
49        match self {
50            Self::V0(v) => &v.features,
51        }
52    }
53
54    /// Returns the block time in ms of the given ER node
55    pub fn block_time_ms(&self) -> u16 {
56        match self {
57            Self::V0(v) => v.block_time_ms,
58        }
59    }
60
61    /// Returns current status of the given ER node
62    pub fn status(&self) -> ErStatus {
63        match self {
64            Self::V0(v) => v.status,
65        }
66    }
67
68    /// Returns load average of the given ER node
69    pub fn load_average(&self) -> u32 {
70        match self {
71            Self::V0(v) => v.load_average,
72        }
73    }
74
75    /// Returns 3 digit country code of the given ER node
76    pub fn country_code(&self) -> CountryCode {
77        match self {
78            Self::V0(v) => v.country_code,
79        }
80    }
81
82    /// Updates the FQDN address in the given ER record
83    pub fn set_addr(&mut self, addr: String) {
84        match self {
85            Self::V0(v) => v.addr = addr,
86        }
87    }
88
89    /// Updates base transaction fee in the given ER record
90    pub fn set_base_fee(&mut self, base_fee: u16) {
91        match self {
92            Self::V0(v) => v.base_fee = base_fee,
93        }
94    }
95
96    /// Updates the features set in the given ER record
97    pub fn set_features(&mut self, features: FeaturesSet) {
98        match self {
99            Self::V0(v) => v.features = features,
100        }
101    }
102
103    /// Updates block time in ms in the given ER record
104    pub fn set_block_time_ms(&mut self, block_time_ms: u16) {
105        match self {
106            Self::V0(v) => v.block_time_ms = block_time_ms,
107        }
108    }
109
110    /// Updates node status for the given ER record
111    pub fn set_status(&mut self, status: ErStatus) {
112        match self {
113            Self::V0(v) => v.status = status,
114        }
115    }
116
117    /// Updates the load average for the given ER record
118    pub fn set_load_average(&mut self, load_average: u32) {
119        match self {
120            Self::V0(v) => v.load_average = load_average,
121        }
122    }
123
124    /// Updates the country code for the given ER record
125    pub fn set_country_code(&mut self, country_code: CountryCode) {
126        match self {
127            Self::V0(v) => v.country_code = country_code,
128        }
129    }
130}
131
132#[derive(BorshDeserialize, BorshSerialize, Debug, Clone, Copy, PartialEq, Eq)]
133pub struct CountryCode([u8; 3]);
134
135impl<S: AsRef<[u8]>> From<S> for CountryCode {
136    fn from(value: S) -> Self {
137        const LEN: usize = std::mem::size_of::<CountryCode>();
138        let mut buf = [0u8; LEN];
139        buf.copy_from_slice(&value.as_ref()[..LEN]);
140        Self(buf)
141    }
142}
143
144impl CountryCode {
145    pub fn as_str(&self) -> Cow<'_, str> {
146        String::from_utf8_lossy(&self.0)
147    }
148}