Skip to content

Commit 99973d1

Browse files
committed
Add helper stacks client functions for getting vote threshold and current vote weight consumed
Signed-off-by: Jacinta Ferrant <[email protected]>
1 parent 284945b commit 99973d1

File tree

2 files changed

+94
-1
lines changed

2 files changed

+94
-1
lines changed

stacks-signer/src/client/mod.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,4 +518,28 @@ pub(crate) mod tests {
518518
db_path: config.db_path.clone(),
519519
}
520520
}
521+
522+
pub fn build_get_round_info_response(info: Option<(u64, u64)>) -> String {
523+
let clarity_value = if let Some((vote_count, vote_weight)) = info {
524+
ClarityValue::some(ClarityValue::Tuple(
525+
TupleData::from_data(vec![
526+
("votes-count".into(), ClarityValue::UInt(vote_count as u128)),
527+
(
528+
"votes-weight".into(),
529+
ClarityValue::UInt(vote_weight as u128),
530+
),
531+
])
532+
.expect("BUG: Failed to create clarity value from tuple data"),
533+
))
534+
.expect("BUG: Failed to create clarity value from tuple data")
535+
} else {
536+
ClarityValue::none()
537+
};
538+
build_read_only_response(&clarity_value)
539+
}
540+
541+
pub fn build_get_weight_threshold_response(threshold: u64) -> String {
542+
let clarity_value = ClarityValue::UInt(threshold as u128);
543+
build_read_only_response(&clarity_value)
544+
}
521545
}

stacks-signer/src/client/stacks_client.rs

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,47 @@ impl StacksClient {
274274
}
275275
}
276276

277+
/// Retrieve the current consumed weight for the given reward cycle and DKG round
278+
pub fn get_round_vote_weight(
279+
&self,
280+
reward_cycle: u64,
281+
round_id: u64,
282+
) -> Result<Option<u128>, ClientError> {
283+
let function_name = ClarityName::from("get-round-info");
284+
let pox_contract_id = boot_code_id(SIGNERS_VOTING_NAME, self.mainnet);
285+
let function_args = &[
286+
ClarityValue::UInt(reward_cycle as u128),
287+
ClarityValue::UInt(round_id as u128),
288+
];
289+
let value = self.read_only_contract_call(
290+
&pox_contract_id.issuer.into(),
291+
&pox_contract_id.name,
292+
&function_name,
293+
function_args,
294+
)?;
295+
let inner_data = value.expect_optional()?;
296+
let Some(inner_data) = inner_data else {
297+
return Ok(None);
298+
};
299+
let round_info = inner_data.expect_tuple()?;
300+
let votes_weight = round_info.get("votes-weight")?.to_owned().expect_u128()?;
301+
Ok(Some(votes_weight))
302+
}
303+
304+
/// Retrieve the weight threshold required to approve a DKG vote
305+
pub fn get_vote_threshold_weight(&self, reward_cycle: u64) -> Result<u128, ClientError> {
306+
let function_name = ClarityName::from("get-threshold-weight");
307+
let pox_contract_id = boot_code_id(SIGNERS_VOTING_NAME, self.mainnet);
308+
let function_args = &[ClarityValue::UInt(reward_cycle as u128)];
309+
let value = self.read_only_contract_call(
310+
&pox_contract_id.issuer.into(),
311+
&pox_contract_id.name,
312+
&function_name,
313+
function_args,
314+
)?;
315+
Ok(value.expect_u128()?)
316+
}
317+
277318
/// Retrieve the current account nonce for the provided address
278319
pub fn get_account_nonce(&self, address: &StacksAddress) -> Result<u64, ClientError> {
279320
let account_entry = self.get_account_entry_with_retry(address)?;
@@ -644,7 +685,8 @@ mod tests {
644685
use crate::client::tests::{
645686
build_account_nonce_response, build_get_approved_aggregate_key_response,
646687
build_get_last_round_response, build_get_peer_info_response, build_get_pox_data_response,
647-
build_get_vote_for_aggregate_key_response, build_read_only_response, write_response,
688+
build_get_round_info_response, build_get_vote_for_aggregate_key_response,
689+
build_get_weight_threshold_response, build_read_only_response, write_response,
648690
MockServerClient,
649691
};
650692

@@ -1194,4 +1236,31 @@ mod tests {
11941236
write_response(mock.server, key_response.as_bytes());
11951237
assert_eq!(h.join().unwrap().unwrap(), None);
11961238
}
1239+
1240+
#[test]
1241+
fn get_round_vote_weight_should_succeed() {
1242+
let mock = MockServerClient::new();
1243+
let vote_count = rand::thread_rng().next_u64();
1244+
let weight = rand::thread_rng().next_u64();
1245+
let round_response = build_get_round_info_response(Some((vote_count, weight)));
1246+
let h = spawn(move || mock.client.get_round_vote_weight(0, 0));
1247+
write_response(mock.server, round_response.as_bytes());
1248+
assert_eq!(h.join().unwrap().unwrap(), Some(weight as u128));
1249+
1250+
let mock = MockServerClient::new();
1251+
let round_response = build_get_round_info_response(None);
1252+
let h = spawn(move || mock.client.get_round_vote_weight(0, 0));
1253+
write_response(mock.server, round_response.as_bytes());
1254+
assert_eq!(h.join().unwrap().unwrap(), None);
1255+
}
1256+
1257+
#[test]
1258+
fn get_vote_threshold_weight_should_succeed() {
1259+
let mock = MockServerClient::new();
1260+
let weight = rand::thread_rng().next_u64();
1261+
let round_response = build_get_weight_threshold_response(weight);
1262+
let h = spawn(move || mock.client.get_vote_threshold_weight(0));
1263+
write_response(mock.server, round_response.as_bytes());
1264+
assert_eq!(h.join().unwrap().unwrap(), weight as u128);
1265+
}
11971266
}

0 commit comments

Comments
 (0)