sp_session_validator_management_query/
commands.rs

1//! Implementations for CLI query commands for getting Ariadne params and registration status
2use crate::SessionValidatorManagementQueryApi;
3use sidechain_domain::{McEpochNumber, StakePoolPublicKey};
4
5/// Returns Ariadne parameters in JSON format that are effective for the given epoch
6/// Arguments:
7///  - query: query api implementing [SessionValidatorManagementQueryApi] trait
8///  - mc_epoch_number: mainchain epoch for which to get Ariadne parameters
9pub 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
21/// Returns Registration status in JSON format
22/// Arguments:
23///  - query: query api implementing [SessionValidatorManagementQueryApi] trait
24///  - mc_epoch_number: mainchain epoch for which to get Registration status
25///  - stake_pool_public_key: stake pool pub key for which to get Registration status
26pub 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(&registrations_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}