sp_session_validator_management_query/
commands.rs1use crate::SessionValidatorManagementQueryApi;
3use sidechain_domain::{McEpochNumber, StakePoolPublicKey};
4
5pub async fn cli_get_ariadne_parameters(
10 query: impl SessionValidatorManagementQueryApi,
11 mc_epoch_number: McEpochNumber,
12) -> Result<String, String> {
13 let ariadne_parameters = query
14 .get_ariadne_parameters(mc_epoch_number)
15 .await
16 .map_err(|err| err.to_string())?;
17 let json = serde_json::to_value(ariadne_parameters).map_err(|err| err.to_string())?;
18 serde_json::to_string_pretty(&json).map_err(|err| err.to_string())
19}
20
21pub async fn cli_get_registration_status(
27 query: impl SessionValidatorManagementQueryApi,
28 mc_epoch_number: McEpochNumber,
29 stake_pool_public_key: StakePoolPublicKey,
30) -> Result<String, String> {
31 let registrations = query
32 .get_registrations(mc_epoch_number, stake_pool_public_key.clone())
33 .await
34 .map_err(|err| err.to_string())?;
35 let registrations_json = serde_json::to_value(registrations).map_err(|err| err.to_string())?;
36 serde_json::to_string_pretty(®istrations_json).map_err(|err| err.to_string())
37}
38
39#[cfg(test)]
40mod tests {
41 use super::*;
42 use crate::{
43 QueryResult,
44 types::{
45 AriadneParameters, CandidateRegistrationEntry, DParameter, GetCommitteeResponse,
46 GetRegistrationsResponseMap, PermissionedCandidateData,
47 },
48 };
49 use async_trait::async_trait;
50 use hex_literal::hex;
51 use serde_json::Value;
52 use sidechain_domain::{
53 McBlockNumber, McSlotNumber, McTxHash, McTxIndexInBlock, SidechainPublicKey,
54 StakePoolPublicKey, UtxoId, UtxoIndex, UtxoInfo, byte_string::ByteString,
55 };
56
57 struct MockSessionValidatorManagementQuery {
58 pub ariadne_parameters: Option<AriadneParameters>,
59 pub expected_registrations: Vec<CandidateRegistrationEntry>,
60 }
61
62 #[async_trait]
63 impl SessionValidatorManagementQueryApi for MockSessionValidatorManagementQuery {
64 fn get_epoch_committee(&self, _: u64) -> QueryResult<GetCommitteeResponse> {
65 unimplemented!()
66 }
67
68 async fn get_registrations(
69 &self,
70 _: McEpochNumber,
71 _: StakePoolPublicKey,
72 ) -> QueryResult<Vec<CandidateRegistrationEntry>> {
73 Ok(self.expected_registrations.clone())
74 }
75
76 async fn get_ariadne_parameters(
77 &self,
78 epoch_number: McEpochNumber,
79 ) -> QueryResult<AriadneParameters> {
80 if epoch_number.0 == 303 {
81 Ok(self.ariadne_parameters.clone().unwrap())
82 } else {
83 Err("unexpected epoch number".into())
84 }
85 }
86 }
87
88 #[tokio::test]
89 async fn ariadne_parameters_returns_correct_json_string() {
90 let d_parameter =
91 DParameter { num_permissioned_candidates: 1, num_registered_candidates: 2 };
92 let permissioned_candidates = vec![PermissionedCandidateData {
93 sidechain_public_key: SidechainPublicKey(
94 hex!("0389411795514af1627765eceffcbd002719f031604fadd7d188e2dc585b4e1afb").to_vec(),
95 ),
96 keys: vec![
97 (
98 "aura".to_string(),
99 ByteString::from_hex_unsafe(
100 "90b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22",
101 ),
102 ),
103 (
104 "gran".to_string(),
105 ByteString::from_hex_unsafe(
106 "439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234f",
107 ),
108 ),
109 ]
110 .into_iter()
111 .collect(),
112 is_valid: true,
113 invalid_reasons: None,
114 }];
115 let candidate_registrations = GetRegistrationsResponseMap::new();
116 let ariadne_parameters = AriadneParameters {
117 d_parameter,
118 permissioned_candidates: Some(permissioned_candidates),
119 candidate_registrations,
120 };
121
122 let query = MockSessionValidatorManagementQuery {
123 ariadne_parameters: Some(ariadne_parameters),
124 expected_registrations: vec![],
125 };
126
127 let cmd_output = cli_get_ariadne_parameters(query, McEpochNumber(303)).await.unwrap();
128
129 assert_eq!(
130 serde_json::from_str::<Value>(&cmd_output).unwrap(),
131 serde_json::json!({
132 "dParameter": {
133 "numPermissionedCandidates": 1,
134 "numRegisteredCandidates": 2
135 },
136 "candidateRegistrations": {},
137 "permissionedCandidates":[
138 {
139 "sidechainPublicKey": "0x0389411795514af1627765eceffcbd002719f031604fadd7d188e2dc585b4e1afb",
140 "keys": {"aura":"0x90b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22", "gran": "0x439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234f"},
141 "isValid": true
142 }
143 ]
144 })
145 );
146 }
147
148 #[tokio::test]
149 async fn cli_get_registration_status_returns_correct_json_string() {
150 let aura = ByteString::from_hex_unsafe(
151 "90b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22",
152 );
153 let grandpa = ByteString::from_hex_unsafe(
154 "439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234f",
155 );
156 let response = vec![CandidateRegistrationEntry {
157 sidechain_pub_key: "0x0389411795514af1627765eceffcbd002719f031604fadd7d188e2dc585b4e1afb".to_string(),
158 sidechain_account_id: "5EP2cMaCxLzhfD3aFAqqgu3kfXH7GcwweEv6JXZRP6ysRHkQ".to_string(),
159 mainchain_pub_key: "0x7521303029fc73ea2dd6a410c4c3cf570bf294a7e02942e049d50ba117acec22".to_string(),
160 cross_chain_pub_key: "0x0389411795514af1627765eceffcbd002719f031604fadd7d188e2dc585b4e1afb".to_string(),
161 keys: vec![("aura".to_string(), aura),("gran".to_string(), grandpa)].into_iter().collect(),
162 sidechain_signature: "0x3da1014f1ba4ece29a82b98e2ee4e707bd062523f558e84857cd97d95c525ebd4762812bc1baaf92117861d41acd8641d474f1b30367f0c1ebcf0d280ec44338".to_string(),
163 mainchain_signature: "0x37a45144a24ddd0ded388b7b39441b4ceb7abd1935d02fe6abf07f14025b663e81b53678b3f6701a7c76af7981246537eeee6a790aac18445bb8494bea38990f".to_string(),
164 cross_chain_signature: "0x3da1014f1ba4ece29a82b98e2ee4e707bd062523f558e84857cd97d95c525ebd4762812bc1baaf92117861d41acd8641d474f1b30367f0c1ebcf0d280ec44338".to_string(),
165 utxo: UtxoInfo {
166 utxo_id: UtxoId {
167 tx_hash: McTxHash(hex!("a40c500e3cd4a374916947bc1ff419d5ed1b3e0bef410ba793c3507703f3d6de")),
168 index: UtxoIndex(0),
169 },
170 epoch_number: McEpochNumber(303),
171 block_number: McBlockNumber(1147672),
172 slot_number: McSlotNumber(26223403),
173 tx_index_within_block: McTxIndexInBlock(0),
174 },
175 stake_delegation: Some(2380000000),
176 is_valid: true,
177 invalid_reasons: None,
178 }];
179
180 let query = MockSessionValidatorManagementQuery {
181 ariadne_parameters: None,
182 expected_registrations: response,
183 };
184
185 let cmd_output = cli_get_registration_status(
186 query,
187 McEpochNumber(303),
188 StakePoolPublicKey(hex!(
189 "7521303029fc73ea2dd6a410c4c3cf570bf294a7e02942e049d50ba117acec22"
190 )),
191 )
192 .await
193 .unwrap();
194
195 assert_eq!(
196 serde_json::from_str::<Value>(&cmd_output).unwrap(),
197 serde_json::json!([{
198 "sidechainPubKey": "0x0389411795514af1627765eceffcbd002719f031604fadd7d188e2dc585b4e1afb",
199 "sidechainAccountId": "5EP2cMaCxLzhfD3aFAqqgu3kfXH7GcwweEv6JXZRP6ysRHkQ",
200 "mainchainPubKey": "0x7521303029fc73ea2dd6a410c4c3cf570bf294a7e02942e049d50ba117acec22",
201 "crossChainPubKey": "0x0389411795514af1627765eceffcbd002719f031604fadd7d188e2dc585b4e1afb",
202 "keys": {"aura":"0x90b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22", "gran":"0x439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234f"},
203 "sidechainSignature": "0x3da1014f1ba4ece29a82b98e2ee4e707bd062523f558e84857cd97d95c525ebd4762812bc1baaf92117861d41acd8641d474f1b30367f0c1ebcf0d280ec44338",
204 "mainchainSignature": "0x37a45144a24ddd0ded388b7b39441b4ceb7abd1935d02fe6abf07f14025b663e81b53678b3f6701a7c76af7981246537eeee6a790aac18445bb8494bea38990f",
205 "crossChainSignature": "0x3da1014f1ba4ece29a82b98e2ee4e707bd062523f558e84857cd97d95c525ebd4762812bc1baaf92117861d41acd8641d474f1b30367f0c1ebcf0d280ec44338",
206 "utxo": {
207 "utxoId": "a40c500e3cd4a374916947bc1ff419d5ed1b3e0bef410ba793c3507703f3d6de#0",
208 "epochNumber": 303,
209 "blockNumber": 1147672,
210 "slotNumber": 26223403,
211 "txIndexWithinBlock": 0,
212 },
213 "stakeDelegation": 2380000000u32,
214 "isValid": true
215 }])
216 );
217 }
218}