Unit tests & minor tweaks

This commit is contained in:
dynco-nym
2025-12-09 16:09:33 +01:00
parent b80f9de18d
commit df93356a23
4 changed files with 244 additions and 17 deletions
@@ -36,13 +36,6 @@ pub enum ExecuteMsg {
data: Vec<NodePerformanceSpecific>,
},
// TODO dz rename to remove speicifc suffix
/// Attempt to submit performance data of a batch of nodes for given epoch
BatchSubmitSpecific {
epoch: EpochId,
data: Vec<NodePerformanceSpecific>,
},
/// Measurement kind needs to be defined by the admin before measurements of
/// that kind can be submitted.
DefineMeasurementKind { measurement_kind: String },
+6 -6
View File
@@ -12,7 +12,8 @@ use crate::storage::NYM_PERFORMANCE_CONTRACT_STORAGE;
use crate::transactions::{
try_authorise_network_monitor, try_batch_submit_performance_results,
try_define_measurement_kind, try_remove_epoch_measurements, try_remove_node_measurements,
try_retire_network_monitor, try_submit_performance_results, try_update_contract_admin,
try_retire_measurement_kind, try_retire_network_monitor, try_submit_performance_results,
try_update_contract_admin,
};
use cosmwasm_std::{
Binary, Deps, DepsMut, Env, MessageInfo, Response, entry_point, to_json_binary,
@@ -63,13 +64,12 @@ pub fn execute(
ExecuteMsg::BatchSubmit { epoch, data } => {
try_batch_submit_performance_results(deps, env, info, epoch, data)
}
// TODO dz implement
ExecuteMsg::BatchSubmitSpecific { epoch, data } => todo!(),
ExecuteMsg::DefineMeasurementKind { measurement_kind } => {
try_define_measurement_kind(deps, info, measurement_kind)
try_define_measurement_kind(deps, &info.sender, measurement_kind)
}
ExecuteMsg::RetireMeasurementKind { measurement_kind } => {
try_retire_measurement_kind(deps, &info.sender, measurement_kind)
}
// TODO dz implement
ExecuteMsg::RetireMeasurementKind { measurement_kind } => todo!(),
ExecuteMsg::AuthoriseNetworkMonitor { address } => {
try_authorise_network_monitor(deps, env, info, address)
}
+19 -1
View File
@@ -634,6 +634,24 @@ impl PerformanceResultsStorage {
.map_err(From::from)
}
/// assumes authorization had been performed
pub fn retire_measurement_kind(
&self,
storage: &mut dyn Storage,
measurement_kind: MeasurementKind,
) -> Result<(), NymPerformanceContractError> {
if !self.is_measurement_defined(storage, measurement_kind.clone())? {
return Err(NymPerformanceContractError::InvalidInput(format!(
"Invalid input: measurement {} not defined",
&measurement_kind
)));
}
self.defined_measurements.remove(storage, measurement_kind);
Ok(())
}
fn update_submission_metadata(
&self,
storage: &mut dyn Storage,
@@ -1309,7 +1327,7 @@ mod tests {
NodePerformanceSpecific {
node_id: nodes[8],
performance: Default::default(),
measurement_kind: measurement_kind,
measurement_kind,
},
)?;
let metadata = storage
+219 -3
View File
@@ -2,7 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
use crate::storage::{MeasurementKind, NYM_PERFORMANCE_CONTRACT_STORAGE};
use cosmwasm_std::{DepsMut, Env, Event, MessageInfo, Response, to_json_binary};
use cosmwasm_std::{Addr, DepsMut, Env, Event, MessageInfo, Response, to_json_binary};
use nym_performance_contract_common::{
EpochId, NodeId, NodePerformanceSpecific, NymPerformanceContractError,
};
@@ -23,12 +23,12 @@ pub fn try_update_contract_admin(
pub fn try_define_measurement_kind(
deps: DepsMut<'_>,
info: MessageInfo,
sender: &Addr,
measurement_kind: MeasurementKind,
) -> Result<Response, NymPerformanceContractError> {
NYM_PERFORMANCE_CONTRACT_STORAGE
.contract_admin
.assert_admin(deps.as_ref(), &info.sender)?;
.assert_admin(deps.as_ref(), sender)?;
NYM_PERFORMANCE_CONTRACT_STORAGE
.performance_results
@@ -37,6 +37,22 @@ pub fn try_define_measurement_kind(
Ok(Response::new())
}
pub fn try_retire_measurement_kind(
deps: DepsMut<'_>,
sender_addr: &Addr,
measurement_kind: MeasurementKind,
) -> Result<Response, NymPerformanceContractError> {
NYM_PERFORMANCE_CONTRACT_STORAGE
.contract_admin
.assert_admin(deps.as_ref(), sender_addr)?;
NYM_PERFORMANCE_CONTRACT_STORAGE
.performance_results
.retire_measurement_kind(deps.storage, measurement_kind)?;
Ok(Response::new())
}
pub fn try_submit_performance_results(
deps: DepsMut<'_>,
env: Env,
@@ -77,6 +93,10 @@ pub fn try_batch_submit_performance_results(
.add_attribute(
"non_existent_nodes",
format!("{:?}", res.non_existent_nodes),
)
.add_attribute(
"non_existent_measurement_kinds",
format!("{:?}", res.non_existent_measurement_kind),
),
);
Ok(response)
@@ -333,4 +353,200 @@ mod tests {
Ok(())
}
mod measurement_kind_authorization {
use cosmwasm_std::testing::message_info;
use nym_contracts_common_testing::{AdminExt, ContractOpts};
use nym_performance_contract_common::NymPerformanceContractError;
use crate::{
storage::MeasurementKind,
testing::{PerformanceContractTesterExt, init_contract_tester},
transactions::{
try_define_measurement_kind, try_retire_measurement_kind,
try_submit_performance_results,
},
};
#[allow(clippy::panic)]
#[test]
fn add_requires_admin() {
let mut tester = init_contract_tester();
let admin = tester.admin_msg();
let new_measurement = MeasurementKind::from("new-measurement");
assert!(
try_define_measurement_kind(
tester.deps_mut(),
&admin.sender,
new_measurement.clone()
)
.is_ok()
);
}
#[allow(clippy::panic)]
#[test]
fn retire_requires_admin() {
let mut tester = init_contract_tester();
let admin = tester.admin_msg();
let new_measurement = MeasurementKind::from("new-measurement");
try_define_measurement_kind(tester.deps_mut(), &admin.sender, new_measurement.clone())
.unwrap();
let unauthorized_addr = tester.addr_make("unauthorized-addr");
let unauthorized = try_retire_measurement_kind(
tester.deps_mut(),
&unauthorized_addr,
new_measurement.clone(),
);
assert!(matches!(
unauthorized,
Err(NymPerformanceContractError::Admin { .. })
));
let authorized = try_retire_measurement_kind(
tester.deps_mut(),
&admin.sender,
new_measurement.clone(),
);
assert!(matches!(authorized, Ok(..)));
}
#[allow(clippy::panic)]
#[test]
fn cannot_add_existing() {
let mut tester = init_contract_tester();
let admin = tester.admin_msg();
let new_measurement = MeasurementKind::from("new-measurement");
let first_attempt = try_define_measurement_kind(
tester.deps_mut(),
&admin.sender,
new_measurement.clone(),
);
assert!(matches!(first_attempt, Ok(..)));
let second_attempt =
try_define_measurement_kind(tester.deps_mut(), &admin.sender, new_measurement);
assert!(matches!(
second_attempt,
Err(NymPerformanceContractError::InvalidInput(_))
));
}
#[allow(clippy::panic)]
#[test]
fn cannot_retire_nonexistent() {
let mut tester = init_contract_tester();
let admin = tester.admin_msg();
let nonexistent = MeasurementKind::from("nonexistent");
let err = try_retire_measurement_kind(tester.deps_mut(), &admin.sender, nonexistent);
assert!(matches!(
err,
Err(NymPerformanceContractError::InvalidInput(_))
));
}
#[allow(clippy::panic)]
#[test]
fn cannot_submit_undefined() {
let mut tester = init_contract_tester();
let env = tester.env();
let admin = tester.admin_msg();
let dummy_perf = tester.dummy_node_performance();
let nm = tester.addr_make("network-monitor");
tester.authorise_network_monitor(&nm).unwrap();
let dummy_measurement = dummy_perf.measurement_kind.clone();
let first_attempt = try_submit_performance_results(
tester.deps_mut(),
env.clone(),
// network monitor submits
message_info(&nm, &[]),
0,
dummy_perf.clone(),
);
assert!(matches!(
first_attempt,
Err(NymPerformanceContractError::UnsupportedMeasurementKind { .. })
));
try_define_measurement_kind(
tester.deps_mut(),
// admin defines
&admin.sender,
dummy_measurement.clone(),
)
.unwrap();
let second_attempt = try_submit_performance_results(
tester.deps_mut(),
env,
// network monitor submits
message_info(&nm, &[]),
0,
dummy_perf,
);
assert!(matches!(second_attempt, Ok(..)));
}
#[allow(clippy::panic)]
#[test]
fn cannot_submit_retired() {
let mut tester = init_contract_tester();
let env = tester.env();
let admin = tester.admin_msg();
let dummy_perf = tester.dummy_node_performance();
let nm = tester.addr_make("network-monitor");
tester.authorise_network_monitor(&nm).unwrap();
let dummy_measurement = dummy_perf.measurement_kind.clone();
try_define_measurement_kind(
tester.deps_mut(),
// admin defines
&admin.sender,
dummy_measurement.clone(),
)
.unwrap();
let defined_ok = try_submit_performance_results(
tester.deps_mut(),
env.clone(),
// network monitor submits
message_info(&nm, &[]),
0,
dummy_perf.clone(),
);
assert!(matches!(defined_ok, Ok(..)));
// can't submit for the same node in the same epoch again
tester.advance_mixnet_epoch().unwrap();
try_retire_measurement_kind(
tester.deps_mut(),
// admin defines
&admin.sender,
dummy_measurement.clone(),
)
.unwrap();
let retired_err = try_submit_performance_results(
tester.deps_mut(),
env,
// network monitor submits
message_info(&nm, &[]),
1,
dummy_perf,
);
println!("{:#?}", retired_err);
assert!(matches!(
retired_err,
Err(NymPerformanceContractError::UnsupportedMeasurementKind { .. })
));
}
}
}