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 AuraPublicKey, GrandpaPublicKey, McBlockNumber, McSlotNumber, McTxHash, McTxIndexInBlock,
54 SidechainPublicKey, StakePoolPublicKey, UtxoId, UtxoIndex, UtxoInfo,
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 aura_public_key: AuraPublicKey(
97 hex!("90b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22").to_vec(),
98 ),
99 grandpa_public_key: GrandpaPublicKey(
100 hex!("439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234f").to_vec(),
101 ),
102 is_valid: true,
103 invalid_reasons: None,
104 }];
105 let candidate_registrations = GetRegistrationsResponseMap::new();
106 let ariadne_parameters = AriadneParameters {
107 d_parameter,
108 permissioned_candidates: Some(permissioned_candidates),
109 candidate_registrations,
110 };
111
112 let query = MockSessionValidatorManagementQuery {
113 ariadne_parameters: Some(ariadne_parameters),
114 expected_registrations: vec![],
115 };
116
117 let cmd_output = cli_get_ariadne_parameters(query, McEpochNumber(303)).await.unwrap();
118
119 assert_eq!(
120 serde_json::from_str::<Value>(&cmd_output).unwrap(),
121 serde_json::json!({
122 "dParameter": {
123 "numPermissionedCandidates": 1,
124 "numRegisteredCandidates": 2
125 },
126 "candidateRegistrations": {},
127 "permissionedCandidates":[
128 {
129 "auraPublicKey": "0x90b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22",
130 "grandpaPublicKey": "0x439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234f",
131 "sidechainPublicKey": "0x0389411795514af1627765eceffcbd002719f031604fadd7d188e2dc585b4e1afb",
132 "isValid": true
133 }
134 ]
135 })
136 );
137 }
138
139 #[tokio::test]
140 async fn cli_get_registration_status_returns_correct_json_string() {
141 let response = vec![CandidateRegistrationEntry {
142 sidechain_pub_key: "0x0389411795514af1627765eceffcbd002719f031604fadd7d188e2dc585b4e1afb".to_string(),
143 sidechain_account_id: "5EP2cMaCxLzhfD3aFAqqgu3kfXH7GcwweEv6JXZRP6ysRHkQ".to_string(),
144 mainchain_pub_key: "0x7521303029fc73ea2dd6a410c4c3cf570bf294a7e02942e049d50ba117acec22".to_string(),
145 cross_chain_pub_key: "0x0389411795514af1627765eceffcbd002719f031604fadd7d188e2dc585b4e1afb".to_string(),
146 aura_pub_key: "90b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22".to_string(),
147 grandpa_pub_key: "439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234f".to_string(),
148 sidechain_signature: "0x3da1014f1ba4ece29a82b98e2ee4e707bd062523f558e84857cd97d95c525ebd4762812bc1baaf92117861d41acd8641d474f1b30367f0c1ebcf0d280ec44338".to_string(),
149 mainchain_signature: "0x37a45144a24ddd0ded388b7b39441b4ceb7abd1935d02fe6abf07f14025b663e81b53678b3f6701a7c76af7981246537eeee6a790aac18445bb8494bea38990f".to_string(),
150 cross_chain_signature: "0x3da1014f1ba4ece29a82b98e2ee4e707bd062523f558e84857cd97d95c525ebd4762812bc1baaf92117861d41acd8641d474f1b30367f0c1ebcf0d280ec44338".to_string(),
151 utxo: UtxoInfo {
152 utxo_id: UtxoId {
153 tx_hash: McTxHash(hex!("a40c500e3cd4a374916947bc1ff419d5ed1b3e0bef410ba793c3507703f3d6de")),
154 index: UtxoIndex(0),
155 },
156 epoch_number: McEpochNumber(303),
157 block_number: McBlockNumber(1147672),
158 slot_number: McSlotNumber(26223403),
159 tx_index_within_block: McTxIndexInBlock(0),
160 },
161 stake_delegation: Some(2380000000),
162 is_valid: true,
163 invalid_reasons: None,
164 }];
165
166 let query = MockSessionValidatorManagementQuery {
167 ariadne_parameters: None,
168 expected_registrations: response,
169 };
170
171 let cmd_output = cli_get_registration_status(
172 query,
173 McEpochNumber(303),
174 StakePoolPublicKey(hex!(
175 "7521303029fc73ea2dd6a410c4c3cf570bf294a7e02942e049d50ba117acec22"
176 )),
177 )
178 .await
179 .unwrap();
180
181 assert_eq!(
182 serde_json::from_str::<Value>(&cmd_output).unwrap(),
183 serde_json::json!([{
184 "sidechainPubKey": "0x0389411795514af1627765eceffcbd002719f031604fadd7d188e2dc585b4e1afb",
185 "sidechainAccountId": "5EP2cMaCxLzhfD3aFAqqgu3kfXH7GcwweEv6JXZRP6ysRHkQ",
186 "mainchainPubKey": "0x7521303029fc73ea2dd6a410c4c3cf570bf294a7e02942e049d50ba117acec22",
187 "crossChainPubKey": "0x0389411795514af1627765eceffcbd002719f031604fadd7d188e2dc585b4e1afb",
188 "auraPubKey": "90b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22",
189 "grandpaPubKey": "439660b36c6c03afafca027b910b4fecf99801834c62a5e6006f27d978de234f",
190 "sidechainSignature": "0x3da1014f1ba4ece29a82b98e2ee4e707bd062523f558e84857cd97d95c525ebd4762812bc1baaf92117861d41acd8641d474f1b30367f0c1ebcf0d280ec44338",
191 "mainchainSignature": "0x37a45144a24ddd0ded388b7b39441b4ceb7abd1935d02fe6abf07f14025b663e81b53678b3f6701a7c76af7981246537eeee6a790aac18445bb8494bea38990f",
192 "crossChainSignature": "0x3da1014f1ba4ece29a82b98e2ee4e707bd062523f558e84857cd97d95c525ebd4762812bc1baaf92117861d41acd8641d474f1b30367f0c1ebcf0d280ec44338",
193 "utxo": {
194 "utxoId": "a40c500e3cd4a374916947bc1ff419d5ed1b3e0bef410ba793c3507703f3d6de#0",
195 "epochNumber": 303,
196 "blockNumber": 1147672,
197 "slotNumber": 26223403,
198 "txIndexWithinBlock": 0,
199 },
200 "stakeDelegation": 2380000000u32,
201 "isValid": true
202 }])
203 );
204 }
205}