fixed linter issues and outdated tests

This commit is contained in:
Jędrzej Stuczyński
2024-10-10 15:38:00 +01:00
parent f76d677f64
commit 45f4eeeff2
28 changed files with 586 additions and 417 deletions
Generated
+88
View File
@@ -300,6 +300,16 @@ dependencies = [
"nom",
]
[[package]]
name = "assert-json-diff"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47e4f2b81832e72834d7518d8487a0396a28cc408186a2e8854c0f98011faf12"
dependencies = [
"serde",
"serde_json",
]
[[package]]
name = "async-channel"
version = "1.9.0"
@@ -396,6 +406,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "auto-future"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c1e7e457ea78e524f48639f551fd79703ac3f2237f5ecccdf4708f8a75ad373"
[[package]]
name = "autocfg"
version = "1.3.0"
@@ -525,6 +541,35 @@ dependencies = [
"tracing",
]
[[package]]
name = "axum-test"
version = "16.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3254184de359bbae2a8ca10b050870a7a4f1c8332a2c27d53f360b9835bb3911"
dependencies = [
"anyhow",
"assert-json-diff",
"auto-future",
"axum 0.7.7",
"bytes",
"cookie",
"http 1.1.0",
"http-body-util",
"hyper 1.4.1",
"hyper-util",
"mime",
"pretty_assertions",
"reserve-port",
"rust-multipart-rfc7578_2",
"serde",
"serde_json",
"serde_urlencoded",
"smallvec",
"tokio",
"tower 0.5.1",
"url",
]
[[package]]
name = "backtrace"
version = "0.3.73"
@@ -2016,6 +2061,12 @@ dependencies = [
"syn 2.0.66",
]
[[package]]
name = "diff"
version = "0.1.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
[[package]]
name = "digest"
version = "0.8.1"
@@ -4256,6 +4307,7 @@ dependencies = [
"async-trait",
"axum 0.7.7",
"axum-extra",
"axum-test",
"bincode",
"bip39",
"bloomfilter",
@@ -7066,6 +7118,16 @@ version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "pretty_assertions"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d"
dependencies = [
"diff",
"yansi",
]
[[package]]
name = "pretty_env_logger"
version = "0.4.0"
@@ -7572,6 +7634,16 @@ dependencies = [
"winreg 0.52.0",
]
[[package]]
name = "reserve-port"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9838134a2bfaa8e1f40738fcc972ac799de6e0e06b5157acb95fc2b05a0ea283"
dependencies = [
"lazy_static",
"thiserror",
]
[[package]]
name = "rfc6979"
version = "0.4.0"
@@ -7782,6 +7854,22 @@ dependencies = [
"walkdir",
]
[[package]]
name = "rust-multipart-rfc7578_2"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03b748410c0afdef2ebbe3685a6a862e2ee937127cdaae623336a459451c8d57"
dependencies = [
"bytes",
"futures-core",
"futures-util",
"http 0.2.12",
"mime",
"mime_guess",
"rand",
"thiserror",
]
[[package]]
name = "rustc-demangle"
version = "0.1.24"
@@ -732,7 +732,6 @@ where
mod tests {
use super::*;
use crate::nyxd::contract_traits::tests::IgnoreValue;
use nym_mixnet_contract_common::QueryMsg;
// it's enough that this compiles and clippy is happy about it
#[allow(dead_code)]
@@ -845,13 +845,6 @@ mod tests {
client.update_nymnode_config(update, None).ignore()
}
ExecuteMsg::TestingUncheckedBondLegacyMixnode { .. } => {
todo!("purposely not implemented")
}
ExecuteMsg::TestingUncheckedBondLegacyGateway { .. } => {
todo!("purposely not implemented")
}
#[cfg(feature = "contract-testing")]
MixnetExecuteMsg::TestingResolveAllPendingEvents { .. } => {
client.testing_resolve_all_pending_events(None).ignore()
@@ -2,13 +2,8 @@
// SPDX-License-Identifier: Apache-2.0
use crate::context::SigningClient;
use anyhow::anyhow;
use crate::validator::mixnet::operators::nymnode;
use clap::Parser;
use cosmwasm_std::Uint128;
use log::info;
use nym_mixnet_contract_common::{NodeCostParams, Percent};
use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, MixnetSigningClient};
use nym_validator_client::nyxd::CosmWasmCoin;
#[derive(Debug, Parser)]
pub struct Args {
@@ -26,48 +21,13 @@ pub struct Args {
}
pub async fn update_cost_params(args: Args, client: SigningClient) -> anyhow::Result<()> {
let denom = client.current_chain_details().mix_denom.base.as_str();
let current_parameters = if let Some(client_mixnode) = client
.get_owned_mixnode(&client.address())
.await?
.mixnode_details
{
client_mixnode.rewarding_details.cost_params
} else {
client
.get_owned_nymnode(&client.address())
.await?
.details
.ok_or_else(|| anyhow!("the client does not own any nodes"))?
.rewarding_details
.cost_params
};
let profit_margin_percent = args
.profit_margin_percent
.map(|pm| Percent::from_percentage_value(pm as u64))
.unwrap_or(Ok(current_parameters.profit_margin_percent))?;
let interval_operating_cost = args
.interval_operating_cost
.map(|oc| CosmWasmCoin {
denom: denom.into(),
amount: Uint128::new(oc),
})
.unwrap_or(current_parameters.interval_operating_cost);
let cost_params = NodeCostParams {
profit_margin_percent,
interval_operating_cost,
};
info!("Starting cost params updating using {cost_params:?} !");
let res = client
.update_cost_params(cost_params, None)
.await
.expect("failed to update cost params");
info!("Cost params result: {:?}", res);
Ok(())
// the below can handle both, nymnode and legacy mixnode
nymnode::settings::update_cost_params::update_cost_params(
nymnode::settings::update_cost_params::Args {
profit_margin_percent: args.profit_margin_percent,
interval_operating_cost: args.interval_operating_cost,
},
client,
)
.await
}
@@ -6,9 +6,7 @@ use anyhow::anyhow;
use clap::Parser;
use cosmwasm_std::Uint128;
use log::info;
use nym_mixnet_contract_common::{
NodeCostParams, Percent, DEFAULT_INTERVAL_OPERATING_COST_AMOUNT, DEFAULT_PROFIT_MARGIN_PERCENT,
};
use nym_mixnet_contract_common::{NodeCostParams, Percent};
use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, MixnetSigningClient};
use nym_validator_client::nyxd::CosmWasmCoin;
@@ -18,7 +16,7 @@ pub struct Args {
long,
help = "input your profit margin as follows; (so it would be 20, rather than 0.2)"
)]
pub profit_margin_percent: Option<u64>,
pub profit_margin_percent: Option<u8>,
#[clap(
long,
@@ -30,37 +28,41 @@ pub struct Args {
pub async fn update_cost_params(args: Args, client: SigningClient) -> anyhow::Result<()> {
let denom = client.current_chain_details().mix_denom.base.as_str();
let default_profit_margin =
Percent::from_percentage_value(DEFAULT_PROFIT_MARGIN_PERCENT).unwrap();
let node_details = client
.get_owned_nymnode(&client.address())
let current_parameters = if let Some(client_mixnode) = client
.get_owned_mixnode(&client.address())
.await?
.details
.ok_or_else(|| anyhow!("the client does not own any nodes"))?;
let current_parameters = node_details.rewarding_details.cost_params;
let profit_margin_percent = current_parameters
.map(|rd| rd.cost_params.profit_margin_percent)
.unwrap_or(default_profit_margin);
let profit_margin_value = args
.profit_margin_percent
.map(|pm| Percent::from_percentage_value(pm as u64))
.unwrap_or(profit_margin_percent)?;
let cost_params = NodeCostParams {
profit_margin_percent: profit_margin_value,
interval_operating_cost: CosmWasmCoin {
denom: denom.into(),
amount: Uint128::new(
args.interval_operating_cost
.unwrap_or(DEFAULT_INTERVAL_OPERATING_COST_AMOUNT),
),
},
.mixnode_details
{
client_mixnode.rewarding_details.cost_params
} else {
client
.get_owned_nymnode(&client.address())
.await?
.details
.ok_or_else(|| anyhow!("the client does not own any nodes"))?
.rewarding_details
.cost_params
};
info!("Starting nym node params updating!");
let profit_margin_percent = args
.profit_margin_percent
.map(|pm| Percent::from_percentage_value(pm as u64))
.unwrap_or(Ok(current_parameters.profit_margin_percent))?;
let interval_operating_cost = args
.interval_operating_cost
.map(|oc| CosmWasmCoin {
denom: denom.into(),
amount: Uint128::new(oc),
})
.unwrap_or(current_parameters.interval_operating_cost);
let cost_params = NodeCostParams {
profit_margin_percent,
interval_operating_cost,
};
info!("Starting cost params updating using {cost_params:?} !");
let res = client
.update_cost_params(cost_params, None)
.await
@@ -272,7 +272,6 @@ impl ContractBuildInformation {
#[cfg(test)]
mod tests {
use super::*;
use cosmwasm_std::Fraction;
#[test]
fn percent_serde() {
@@ -369,7 +369,7 @@ impl Interval {
}
pub fn ensure_current_epoch_is_over(&self, env: &Env) -> Result<(), MixnetContractError> {
if !self.is_current_epoch_over(&env) {
if !self.is_current_epoch_over(env) {
return Err(MixnetContractError::EpochInProgress {
current_block_time: env.block.time.seconds(),
epoch_start: self.current_epoch_start_unix_timestamp(),
@@ -287,7 +287,6 @@ impl NymNodeDetails {
}
}
///
#[cw_serde]
pub struct NymNodeBond {
/// Unique id assigned to the bonded node.
@@ -18,11 +18,3 @@ pub fn truncate_reward(reward: Decimal, denom: impl Into<String>) -> Coin {
pub fn truncate_reward_amount(reward: Decimal) -> Uint128 {
truncate_decimal(reward)
}
pub fn legacy_standby_work_factor() -> Decimal {
todo!()
}
pub fn legacy_active_work_factor() -> Decimal {
todo!()
}
+1 -4
View File
@@ -235,7 +235,6 @@ mod message_receiver {
1,
vec![mix::LegacyNode {
mix_id: 123,
owner: None,
host: "10.20.30.40".parse().unwrap(),
mix_host: "10.20.30.40:1789".parse().unwrap(),
identity_key: identity::PublicKey::from_base58_string(
@@ -255,7 +254,6 @@ mod message_receiver {
2,
vec![mix::LegacyNode {
mix_id: 234,
owner: None,
host: "11.21.31.41".parse().unwrap(),
mix_host: "11.21.31.41:1789".parse().unwrap(),
identity_key: identity::PublicKey::from_base58_string(
@@ -275,7 +273,6 @@ mod message_receiver {
3,
vec![mix::LegacyNode {
mix_id: 456,
owner: None,
host: "12.22.32.42".parse().unwrap(),
mix_host: "12.22.32.42:1789".parse().unwrap(),
identity_key: identity::PublicKey::from_base58_string(
@@ -295,7 +292,7 @@ mod message_receiver {
// currently coco_nodes don't really exist so this is still to be determined
mixes,
vec![gateway::LegacyNode {
owner: None,
node_id: 789,
host: "1.2.3.4".parse().unwrap(),
mix_host: "1.2.3.4:1789".parse().unwrap(),
clients_ws_port: 9000,
+49 -6
View File
@@ -4,12 +4,13 @@
use crate::currency::{DecCoin, RegisteredCoins};
use crate::error::TypesError;
use crate::mixnode::NodeCostParams;
use nym_mixnet_contract_common::reward_params::ActiveSetUpdate;
use nym_mixnet_contract_common::{
BlockHeight, EpochEventId, IntervalEventId, IntervalRewardingParamsUpdate, NodeId,
PendingEpochEvent as MixnetContractPendingEpochEvent,
PendingEpochEventKind as MixnetContractPendingEpochEventKind,
PendingIntervalEvent as MixnetContractPendingIntervalEvent,
PendingIntervalEventKind as MixnetContractPendingIntervalEventKind,
PendingIntervalEventKind as MixnetContractPendingIntervalEventKind, PendingIntervalEventKind,
};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
@@ -22,7 +23,7 @@ use serde::{Deserialize, Serialize};
export_to = "ts-packages/types/src/types/rust/PendingEpochEvent.ts"
)
)]
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, JsonSchema)]
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, JsonSchema)]
pub struct PendingEpochEvent {
pub id: EpochEventId,
pub created_at: BlockHeight,
@@ -50,7 +51,7 @@ impl PendingEpochEvent {
export_to = "ts-packages/types/src/types/rust/PendingEpochEventData.ts"
)
)]
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq, JsonSchema)]
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, JsonSchema)]
pub enum PendingEpochEventData {
Delegate {
owner: String,
@@ -77,6 +78,20 @@ pub enum PendingEpochEventData {
UpdateActiveSetSize {
new_size: u32,
},
NymNodePledgeMore {
node_id: NodeId,
amount: DecCoin,
},
NymNodeDecreasePledge {
node_id: NodeId,
decrease_by: DecCoin,
},
UnbondNymNode {
node_id: NodeId,
},
UpdateActiveSet {
update: ActiveSetUpdate,
},
}
impl PendingEpochEventData {
@@ -123,7 +138,25 @@ impl PendingEpochEventData {
MixnetContractPendingEpochEventKind::UnbondMixnode { mix_id } => {
Ok(PendingEpochEventData::UnbondMixnode { mix_id })
}
_ => todo!(),
MixnetContractPendingEpochEventKind::NymNodePledgeMore { node_id, amount } => {
Ok(PendingEpochEventData::NymNodePledgeMore {
node_id,
amount: reg.attempt_convert_to_display_dec_coin(amount.into())?,
})
}
MixnetContractPendingEpochEventKind::NymNodeDecreasePledge {
node_id,
decrease_by,
} => Ok(PendingEpochEventData::NymNodeDecreasePledge {
node_id,
decrease_by: reg.attempt_convert_to_display_dec_coin(decrease_by.into())?,
}),
MixnetContractPendingEpochEventKind::UnbondNymNode { node_id } => {
Ok(PendingEpochEventData::UnbondNymNode { node_id })
}
MixnetContractPendingEpochEventKind::UpdateActiveSet { update } => {
Ok(PendingEpochEventData::UpdateActiveSet { update })
}
}
}
}
@@ -173,7 +206,10 @@ pub enum PendingIntervalEventData {
mix_id: NodeId,
new_costs: NodeCostParams,
},
ChangeNymNodeCostParams {
node_id: NodeId,
new_costs: NodeCostParams,
},
UpdateRewardingParams {
update: IntervalRewardingParamsUpdate,
},
@@ -207,7 +243,14 @@ impl PendingIntervalEventData {
epochs_in_interval,
epoch_duration_secs,
}),
_ => todo!(),
PendingIntervalEventKind::ChangeNymNodeCostParams { node_id, new_costs } => {
Ok(PendingIntervalEventData::ChangeNymNodeCostParams {
node_id,
new_costs: NodeCostParams::from_mixnet_contract_mixnode_cost_params(
new_costs, reg,
)?,
})
}
}
}
}
@@ -4,6 +4,7 @@
use crate::support::setup::{MIX_DENOM, REWARDING_VALIDATOR};
use cosmwasm_std::Decimal;
use nym_contracts_common::Percent;
use nym_mixnet_contract_common::reward_params::RewardedSetParams;
use nym_mixnet_contract_common::InitialRewardingParams;
use std::time::Duration;
@@ -21,8 +22,12 @@ pub fn default_mixnet_init_msg() -> nym_mixnet_contract_common::InstantiateMsg {
sybil_resistance: Percent::from_percentage_value(30).unwrap(),
active_set_work_factor: Decimal::from_atomics(10u32, 0).unwrap(),
interval_pool_emission: Percent::from_percentage_value(2).unwrap(),
rewarded_set_size: 240,
active_set_size: 100,
rewarded_set_params: RewardedSetParams {
entry_gateways: 70,
exit_gateways: 50,
mixnodes: 120,
standby: 0,
},
},
profit_margin: Default::default(),
interval_operating_cost: Default::default(),
@@ -5,14 +5,15 @@ use crate::support::fixtures;
use crate::support::helpers::{
mixnet_contract_wrapper, rewarding_validator, test_rng, vesting_contract_wrapper,
};
use cosmwasm_std::{coins, Addr, Coin, Timestamp};
use cosmwasm_std::{coins, Addr, Coin, Decimal, Timestamp};
use cw_multi_test::{App, AppBuilder, Executor};
use nym_contracts_common::signing::{ContractMessageContent, MessageSignature, Nonce};
use nym_crypto::asymmetric::identity;
use nym_mixnet_contract_common::reward_params::Performance;
use nym_mixnet_contract_common::nym_node::{EpochAssignmentResponse, Role, RolesMetadataResponse};
use nym_mixnet_contract_common::reward_params::{NodeRewardingParameters, Performance};
use nym_mixnet_contract_common::{
CurrentIntervalResponse, LayerAssignment, MixnodeBondingPayload, NodeCostParams,
PagedRewardedSetResponse, RewardingParams, SignableMixNodeBondingMsg,
CurrentIntervalResponse, MixnodeBondingPayload, NodeCostParams, RewardedSet, RewardingParams,
RoleAssignment, SignableMixNodeBondingMsg,
};
use nym_mixnet_contract_common::{
ExecuteMsg as MixnetExecuteMsg, MixNode, QueryMsg as MixnetQueryMsg,
@@ -118,18 +119,95 @@ impl TestSetup {
})
}
pub fn full_mixnet_epoch_operations(&mut self) {
let current_rewarded_set: PagedRewardedSetResponse = self
fn get_rewarded_set(&self) -> RewardedSet {
let metadata: RolesMetadataResponse = self
.app
.wrap()
.query_wasm_smart(
self.mixnet_contract(),
&MixnetQueryMsg::GetRewardedSet {
limit: Some(9999),
start_after: None,
&MixnetQueryMsg::GetRewardedSetMetadata {},
)
.unwrap();
let entry: EpochAssignmentResponse = self
.app
.wrap()
.query_wasm_smart(
self.mixnet_contract(),
&MixnetQueryMsg::GetRoleAssignment {
role: Role::EntryGateway,
},
)
.unwrap();
assert_eq!(entry.epoch_id, metadata.metadata.epoch_id);
let exit: EpochAssignmentResponse = self
.app
.wrap()
.query_wasm_smart(
self.mixnet_contract(),
&MixnetQueryMsg::GetRoleAssignment {
role: Role::ExitGateway,
},
)
.unwrap();
assert_eq!(exit.epoch_id, metadata.metadata.epoch_id);
let layer1: EpochAssignmentResponse = self
.app
.wrap()
.query_wasm_smart(
self.mixnet_contract(),
&MixnetQueryMsg::GetRoleAssignment { role: Role::Layer1 },
)
.unwrap();
assert_eq!(layer1.epoch_id, metadata.metadata.epoch_id);
let layer2: EpochAssignmentResponse = self
.app
.wrap()
.query_wasm_smart(
self.mixnet_contract(),
&MixnetQueryMsg::GetRoleAssignment { role: Role::Layer2 },
)
.unwrap();
assert_eq!(layer2.epoch_id, metadata.metadata.epoch_id);
let layer3: EpochAssignmentResponse = self
.app
.wrap()
.query_wasm_smart(
self.mixnet_contract(),
&MixnetQueryMsg::GetRoleAssignment { role: Role::Layer3 },
)
.unwrap();
assert_eq!(layer3.epoch_id, metadata.metadata.epoch_id);
let standby: EpochAssignmentResponse = self
.app
.wrap()
.query_wasm_smart(
self.mixnet_contract(),
&MixnetQueryMsg::GetRoleAssignment {
role: Role::Standby,
},
)
.unwrap();
assert_eq!(standby.epoch_id, metadata.metadata.epoch_id);
RewardedSet {
entry_gateways: entry.nodes,
exit_gateways: exit.nodes,
layer1: layer1.nodes,
layer2: layer2.nodes,
layer3: layer3.nodes,
standby: standby.nodes,
}
}
pub fn full_mixnet_epoch_operations(&mut self) {
let rewarded_set = self.get_rewarded_set();
let current_params: RewardingParams = self
.app
.wrap()
@@ -150,16 +228,30 @@ impl TestSetup {
)
.unwrap();
let work =
Decimal::one() / Decimal::from_ratio(rewarded_set.rewarded_set_size() as u64, 1u64);
let params = NodeRewardingParameters::new(Performance::hundred(), work);
let mut nodes = rewarded_set
.layer1
.iter()
.chain(rewarded_set.layer2.iter())
.chain(rewarded_set.layer3.iter())
.chain(rewarded_set.entry_gateways.iter())
.chain(rewarded_set.exit_gateways.iter())
.chain(rewarded_set.standby.iter())
.copied()
.collect::<Vec<_>>();
nodes.sort();
// reward
for (mix_id, _status) in &current_rewarded_set.nodes {
for (node_id) in nodes {
self.app
.execute_contract(
rewarding_validator(),
self.mixnet_contract(),
&MixnetExecuteMsg::RewardNode {
node_id: *mix_id,
performance: Performance::hundred(),
},
&MixnetExecuteMsg::RewardNode { node_id, params },
&[],
)
.unwrap();
@@ -176,22 +268,86 @@ impl TestSetup {
.unwrap();
// don't bother changing the active set, use the same node for update and advance
let new_rewarded_set = current_rewarded_set
.nodes
.into_iter()
.enumerate()
.map(|(i, (node, _))| {
LayerAssignment::new(node, ((i as u8 % 3) + 1).try_into().unwrap())
})
.collect();
self.app
.execute_contract(
rewarding_validator(),
self.mixnet_contract(),
&MixnetExecuteMsg::AdvanceCurrentEpoch {
new_rewarded_set,
expected_active_set_size: current_params.active_set_size,
&MixnetExecuteMsg::AssignRoles {
assignment: RoleAssignment {
role: Role::EntryGateway,
nodes: rewarded_set.entry_gateways,
},
},
&[],
)
.unwrap();
self.app
.execute_contract(
rewarding_validator(),
self.mixnet_contract(),
&MixnetExecuteMsg::AssignRoles {
assignment: RoleAssignment {
role: Role::ExitGateway,
nodes: rewarded_set.exit_gateways,
},
},
&[],
)
.unwrap();
self.app
.execute_contract(
rewarding_validator(),
self.mixnet_contract(),
&MixnetExecuteMsg::AssignRoles {
assignment: RoleAssignment {
role: Role::Layer1,
nodes: rewarded_set.layer1,
},
},
&[],
)
.unwrap();
self.app
.execute_contract(
rewarding_validator(),
self.mixnet_contract(),
&MixnetExecuteMsg::AssignRoles {
assignment: RoleAssignment {
role: Role::Layer2,
nodes: rewarded_set.layer2,
},
},
&[],
)
.unwrap();
self.app
.execute_contract(
rewarding_validator(),
self.mixnet_contract(),
&MixnetExecuteMsg::AssignRoles {
assignment: RoleAssignment {
role: Role::Layer3,
nodes: rewarded_set.layer3,
},
},
&[],
)
.unwrap();
self.app
.execute_contract(
rewarding_validator(),
self.mixnet_contract(),
&MixnetExecuteMsg::AssignRoles {
assignment: RoleAssignment {
role: Role::Standby,
nodes: rewarded_set.standby,
},
},
&[],
)
+1
View File
@@ -134,6 +134,7 @@ sqlx = { workspace = true, features = [
] }
[dev-dependencies]
axum-test = "16.2.0"
tempfile = { workspace = true }
cw3 = { workspace = true }
cw-utils = { workspace = true }
+1 -1
View File
@@ -383,7 +383,7 @@ pub struct EpochCredentialsResponse {
#[derive(Clone, Serialize, Deserialize, Debug, JsonSchema, ToSchema)]
#[serde(rename_all = "camelCase")]
pub struct IssuedCredentialsResponse {
// note: BTreeMap returns ordered results so it's fine to use it with pagination
// note: BTreeMap returns ordered results, so it's fine to use it with pagination
pub credentials: BTreeMap<i64, IssuedTicketbookBody>,
}
+40 -57
View File
@@ -2,12 +2,12 @@
// SPDX-License-Identifier: GPL-3.0-only
use crate::ecash::tests::{voucher_fixture, TestFixture};
use axum::http::StatusCode;
use nym_api_requests::ecash::models::{
EpochCredentialsResponse, IssuedCredentialResponse, IssuedCredentialsResponse, Pagination,
};
use nym_api_requests::ecash::CredentialsRequestBody;
use nym_validator_client::nym_api::routes::{API_VERSION, ECASH_ROUTES};
use rocket::http::Status;
use std::collections::BTreeMap;
#[tokio::test]
@@ -19,11 +19,10 @@ async fn epoch_credentials() {
let test_fixture = TestFixture::new().await;
// initially we expect 0 issued
let response = test_fixture.rocket.get(&route_epoch1).dispatch().await;
let response = test_fixture.axum.get(&route_epoch1).await;
assert_eq!(response.status(), Status::Ok);
let parsed_response: EpochCredentialsResponse =
serde_json::from_str(&response.into_string().await.unwrap()).unwrap();
assert_eq!(response.status_code(), StatusCode::OK);
let parsed_response: EpochCredentialsResponse = response.json();
assert_eq!(parsed_response.epoch_id, 1);
assert_eq!(parsed_response.total_issued, 0);
@@ -33,10 +32,9 @@ async fn epoch_credentials() {
test_fixture.issue_dummy_credential().await;
// now there should be one
let response = test_fixture.rocket.get(&route_epoch1).dispatch().await;
assert_eq!(response.status(), Status::Ok);
let parsed_response: EpochCredentialsResponse =
serde_json::from_str(&response.into_string().await.unwrap()).unwrap();
let response = test_fixture.axum.get(&route_epoch1).await;
assert_eq!(response.status_code(), StatusCode::OK);
let parsed_response: EpochCredentialsResponse = response.json();
assert_eq!(parsed_response.epoch_id, 1);
assert_eq!(parsed_response.total_issued, 1);
@@ -45,11 +43,10 @@ async fn epoch_credentials() {
// and another
test_fixture.issue_dummy_credential().await;
let response = test_fixture.rocket.get(&route_epoch1).dispatch().await;
let response = test_fixture.axum.get(&route_epoch1).await;
assert_eq!(response.status(), Status::Ok);
let parsed_response: EpochCredentialsResponse =
serde_json::from_str(&response.into_string().await.unwrap()).unwrap();
assert_eq!(response.status_code(), StatusCode::OK);
let parsed_response: EpochCredentialsResponse = response.json();
// note that first epoch credential didn't change
assert_eq!(parsed_response.epoch_id, 1);
@@ -58,10 +55,9 @@ async fn epoch_credentials() {
test_fixture.set_epoch(2);
let response = test_fixture.rocket.get(&route_epoch2).dispatch().await;
assert_eq!(response.status(), Status::Ok);
let parsed_response: EpochCredentialsResponse =
serde_json::from_str(&response.into_string().await.unwrap()).unwrap();
let response = test_fixture.axum.get(&route_epoch2).await;
assert_eq!(response.status_code(), StatusCode::OK);
let parsed_response: EpochCredentialsResponse = response.json();
// note the epoch change
assert_eq!(parsed_response.epoch_id, 2);
@@ -70,10 +66,9 @@ async fn epoch_credentials() {
test_fixture.issue_dummy_credential().await;
let response = test_fixture.rocket.get(&route_epoch2).dispatch().await;
assert_eq!(response.status(), Status::Ok);
let parsed_response: EpochCredentialsResponse =
serde_json::from_str(&response.into_string().await.unwrap()).unwrap();
let response = test_fixture.axum.get(&route_epoch2).await;
assert_eq!(response.status_code(), StatusCode::OK);
let parsed_response: EpochCredentialsResponse = response.json();
// note the epoch change
assert_eq!(parsed_response.epoch_id, 2);
@@ -81,10 +76,9 @@ async fn epoch_credentials() {
assert_eq!(parsed_response.first_epoch_credential_id, Some(3));
// random epoch in the future
let response = test_fixture.rocket.get(&route_epoch42).dispatch().await;
assert_eq!(response.status(), Status::Ok);
let parsed_response: EpochCredentialsResponse =
serde_json::from_str(&response.into_string().await.unwrap()).unwrap();
let response = test_fixture.axum.get(&route_epoch42).await;
assert_eq!(response.status_code(), StatusCode::OK);
let parsed_response: EpochCredentialsResponse = response.json();
assert_eq!(parsed_response.epoch_id, 42);
assert_eq!(parsed_response.total_issued, 0);
assert_eq!(parsed_response.first_epoch_credential_id, None);
@@ -114,10 +108,9 @@ async fn issued_credential() {
test_fixture.add_deposit(&voucher2);
// random credential that was never issued
let response = test_fixture.rocket.get(route(42)).dispatch().await;
assert_eq!(response.status(), Status::Ok);
let parsed_response: IssuedCredentialResponse =
serde_json::from_str(&response.into_string().await.unwrap()).unwrap();
let response = test_fixture.axum.get(&route(42)).await;
assert_eq!(response.status_code(), StatusCode::OK);
let parsed_response: IssuedCredentialResponse = response.json();
assert!(parsed_response.credential.is_none());
let cred1 = test_fixture.issue_credential(request1.clone()).await;
@@ -125,16 +118,14 @@ async fn issued_credential() {
test_fixture.set_epoch(3);
let cred2 = test_fixture.issue_credential(request2.clone()).await;
let response = test_fixture.rocket.get(route(1)).dispatch().await;
assert_eq!(response.status(), Status::Ok);
let parsed_response: IssuedCredentialResponse =
serde_json::from_str(&response.into_string().await.unwrap()).unwrap();
let response = test_fixture.axum.get(&route(1)).await;
assert_eq!(response.status_code(), StatusCode::OK);
let parsed_response: IssuedCredentialResponse = response.json();
let issued1 = parsed_response.credential.unwrap();
let response = test_fixture.rocket.get(route(2)).dispatch().await;
assert_eq!(response.status(), Status::Ok);
let parsed_response: IssuedCredentialResponse =
serde_json::from_str(&response.into_string().await.unwrap()).unwrap();
let response = test_fixture.axum.get(&route(2)).await;
assert_eq!(response.status_code(), StatusCode::OK);
let parsed_response: IssuedCredentialResponse = response.json();
let issued2 = parsed_response.credential.unwrap();
// TODO: currently we have no signature checks
@@ -192,37 +183,33 @@ async fn issued_credentials() {
let issued13 = test_fixture.issued_unchecked(13).await;
let response = test_fixture
.rocket
.axum
.post(&route)
.json(&CredentialsRequestBody {
credential_ids: vec![5],
pagination: None,
})
.dispatch()
.await;
assert_eq!(response.status(), Status::Ok);
let parsed_response: IssuedCredentialsResponse =
serde_json::from_str(&response.into_string().await.unwrap()).unwrap();
assert_eq!(response.status_code(), StatusCode::OK);
let parsed_response: IssuedCredentialsResponse = response.json();
assert_eq!(parsed_response.credentials[&5], issued5);
assert!(!parsed_response.credentials.contains_key(&13));
let response = test_fixture
.rocket
.axum
.post(&route)
.json(&CredentialsRequestBody {
credential_ids: vec![5, 13],
pagination: None,
})
.dispatch()
.await;
assert_eq!(response.status(), Status::Ok);
let parsed_response: IssuedCredentialsResponse =
serde_json::from_str(&response.into_string().await.unwrap()).unwrap();
assert_eq!(response.status_code(), StatusCode::OK);
let parsed_response: IssuedCredentialsResponse = response.json();
assert_eq!(parsed_response.credentials[&5], issued5);
assert_eq!(parsed_response.credentials[&13], issued13);
let response_paginated = test_fixture
.rocket
.axum
.post(&route)
.json(&CredentialsRequestBody {
credential_ids: vec![],
@@ -231,11 +218,9 @@ async fn issued_credentials() {
limit: Some(2),
}),
})
.dispatch()
.await;
assert_eq!(response_paginated.status(), Status::Ok);
let parsed_response: IssuedCredentialsResponse =
serde_json::from_str(&response_paginated.into_string().await.unwrap()).unwrap();
assert_eq!(response_paginated.status_code(), StatusCode::OK);
let parsed_response: IssuedCredentialsResponse = response_paginated.json();
let mut expected = BTreeMap::new();
expected.insert(1, issued1);
@@ -243,7 +228,7 @@ async fn issued_credentials() {
assert_eq!(expected, parsed_response.credentials);
let response_paginated = test_fixture
.rocket
.axum
.post(&route)
.json(&CredentialsRequestBody {
credential_ids: vec![],
@@ -252,11 +237,9 @@ async fn issued_credentials() {
limit: Some(3),
}),
})
.dispatch()
.await;
assert_eq!(response_paginated.status(), Status::Ok);
let parsed_response: IssuedCredentialsResponse =
serde_json::from_str(&response_paginated.into_string().await.unwrap()).unwrap();
assert_eq!(response_paginated.status_code(), StatusCode::OK);
let parsed_response: IssuedCredentialsResponse = response_paginated.json();
let mut expected = BTreeMap::new();
expected.insert(3, issued3);
+65 -59
View File
@@ -1,13 +1,24 @@
// Copyright 2022-2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only
use crate::ecash;
use crate::circulating_supply_api::cache::CirculatingSupplyCache;
use crate::ecash::api_routes::handlers::ecash_routes;
use crate::ecash::error::{EcashError, Result};
use crate::ecash::keys::KeyPairWithEpoch;
use crate::ecash::state::EcashState;
use crate::ecash::storage::EcashStorageExt;
use crate::network::models::NetworkDetails;
use crate::node_describe_cache::DescribedNodes;
use crate::node_status_api::handlers::unstable;
use crate::node_status_api::NodeStatusCache;
use crate::nym_contract_cache::cache::NymContractCache;
use crate::support::caching::cache::SharedCache;
use crate::support::http::state::AppState;
use crate::support::storage::NymApiStorage;
use async_trait::async_trait;
use axum::Router;
use axum_test::http::StatusCode;
use axum_test::TestServer;
use cosmwasm_std::testing::{mock_env, mock_info};
use cosmwasm_std::{
from_binary, to_binary, Addr, Binary, BlockInfo, CosmosMsg, Decimal, MessageInfo, WasmMsg,
@@ -31,6 +42,7 @@ use nym_coconut_dkg_common::types::{
use nym_coconut_dkg_common::verification_key::{ContractVKShare, VerificationKeyShare};
use nym_compact_ecash::BlindedSignature;
use nym_compact_ecash::{ttp_keygen, VerificationKeyAuth};
use nym_config::defaults::NymNetworkDetails;
use nym_contracts_common::IdentityKey;
use nym_credentials::IssuanceTicketBook;
use nym_credentials_interface::TicketType;
@@ -45,8 +57,6 @@ use nym_validator_client::nyxd::{AccountId, ExecTxResult, Fee, Hash, TxResponse}
use nym_validator_client::{EcashApiClient, NymApiClient};
use rand::rngs::OsRng;
use rand::RngCore;
use rocket::http::Status;
use rocket::local::asynchronous::Client;
use std::collections::{BTreeMap, HashMap};
use std::ops::Deref;
use std::str::FromStr;
@@ -863,7 +873,7 @@ impl super::client::Client for DummyClient {
.votes
.contains_key(&(voter.clone(), proposal_id))
{
todo!("already voted");
panic!("unhandled case: already voted");
}
chain.multisig_contract.votes.insert(
(voter.clone(), proposal_id),
@@ -1234,7 +1244,7 @@ fn dummy_signature() -> identity::Signature {
}
struct TestFixture {
rocket: Client,
axum: TestServer,
storage: NymApiStorage,
chain_state: SharedFakeChain,
epoch: Arc<AtomicU64>,
@@ -1243,6 +1253,21 @@ struct TestFixture {
}
impl TestFixture {
fn build_app_state(storage: NymApiStorage) -> AppState {
AppState {
nym_contract_cache: NymContractCache::new(),
node_status_cache: NodeStatusCache::new(),
circulating_supply_cache: CirculatingSupplyCache::new("unym".to_owned()),
storage,
described_nodes_cache: SharedCache::<DescribedNodes>::new(),
network_details: NetworkDetails::new(
"localhost".to_string(),
NymNetworkDetails::new_empty(),
),
node_info_cache: unstable::NodeInfoCache::default(),
}
}
async fn new() -> Self {
let mut rng = crate::ecash::tests::fixtures::test_rng([69u8; 32]);
let coconut_keypair = ttp_keygen(1, 1).unwrap().remove(0);
@@ -1283,28 +1308,24 @@ impl TestFixture {
.parse()
.unwrap();
let rocket = rocket::build()
.manage(
EcashState::new(
ecash_contract,
nyxd_client,
identity,
staged_key_pair,
comm_channel,
storage.clone(),
)
.await
.unwrap(),
)
.mount(
"/v1/ecash",
ecash::routes_open_api(&Default::default(), true).0,
);
let ecash_state = EcashState::new(
ecash_contract,
nyxd_client,
identity,
staged_key_pair,
comm_channel,
storage.clone(),
)
.await
.unwrap();
TestFixture {
rocket: Client::tracked(rocket)
.await
.expect("valid rocket instance"),
axum: TestServer::new(
Router::new()
.nest("/v1/ecash", ecash_routes(Arc::new(ecash_state)))
.with_state(Self::build_app_state(storage.clone())),
)
.unwrap(),
storage,
chain_state,
epoch,
@@ -1351,26 +1372,24 @@ impl TestFixture {
async fn issue_credential(&self, req: BlindSignRequestBody) -> BlindedSignatureResponse {
let response = self
.rocket
.post(format!("/{API_VERSION}/{ECASH_ROUTES}/{ECASH_BLIND_SIGN}",))
.axum
.post(&format!("/{API_VERSION}/{ECASH_ROUTES}/{ECASH_BLIND_SIGN}",))
.json(&req)
.dispatch()
.await;
assert_eq!(response.status(), Status::Ok);
serde_json::from_str(&response.into_string().await.unwrap()).unwrap()
assert_eq!(response.status_code(), StatusCode::OK);
response.json()
}
async fn issued_credential(&self, id: i64) -> Option<IssuedCredentialResponse> {
let response = self
.rocket
.get(format!(
.axum
.get(&format!(
"/{API_VERSION}/{ECASH_ROUTES}/issued-credential/{id}"
))
.dispatch()
.await;
assert_eq!(response.status(), Status::Ok);
serde_json::from_str(&response.into_string().await.unwrap()).unwrap()
assert_eq!(response.status_code(), StatusCode::OK);
response.json()
}
async fn issued_unchecked(&self, id: i64) -> IssuedTicketbookBody {
@@ -1385,6 +1404,7 @@ impl TestFixture {
#[cfg(test)]
mod credential_tests {
use super::*;
use axum::http::StatusCode;
use nym_compact_ecash::ttp_keygen;
#[tokio::test]
@@ -1416,23 +1436,15 @@ mod credential_tests {
.unwrap();
let response = test_fixture
.rocket
.post(format!("/{API_VERSION}/{ECASH_ROUTES}/{ECASH_BLIND_SIGN}",))
.axum
.post(&format!("/{API_VERSION}/{ECASH_ROUTES}/{ECASH_BLIND_SIGN}",))
.json(&request_body)
.dispatch()
.await;
assert_eq!(response.status(), Status::Ok);
let expected_response = BlindedSignatureResponse::new(sig);
// This is a more direct way, but there's a bug which makes it hang https://github.com/SergioBenitez/Rocket/issues/1893
// let blinded_signature_response = response
// .into_json::<BlindedSignatureResponse>()
// .await
// .unwrap();
let blinded_signature_response = serde_json::from_str::<BlindedSignatureResponse>(
&response.into_string().await.unwrap(),
)
.unwrap();
assert_eq!(response.status_code(), StatusCode::OK);
let expected_response = BlindedSignatureResponse::new(sig);
let blinded_signature_response = response.json::<BlindedSignatureResponse>();
assert_eq!(
blinded_signature_response.to_bytes(),
expected_response.to_bytes()
@@ -1596,19 +1608,13 @@ mod credential_tests {
let request_body = voucher.create_blind_sign_request_body(&signing_data);
let response = test
.rocket
.post(format!("/{API_VERSION}/{ECASH_ROUTES}/{ECASH_BLIND_SIGN}"))
.axum
.post(&format!("/{API_VERSION}/{ECASH_ROUTES}/{ECASH_BLIND_SIGN}"))
.json(&request_body)
.dispatch()
.await;
assert_eq!(response.status(), Status::Ok);
// This is a more direct way, but there's a bug which makes it hang https://github.com/SergioBenitez/Rocket/issues/1893
// assert!(response.into_json::<BlindedSignatureResponse>().is_some());
let blinded_signature_response = serde_json::from_str::<BlindedSignatureResponse>(
&response.into_string().await.unwrap(),
);
assert!(blinded_signature_response.is_ok());
assert_eq!(response.status_code(), StatusCode::OK);
let _ = response.json::<BlindedSignatureResponse>();
}
#[test]
+4 -1
View File
@@ -119,7 +119,10 @@ impl EpochAdvancer {
let legacy_mixnodes = self.nym_contract_cache.legacy_mixnodes_filtered().await;
let legacy_gateways = self.nym_contract_cache.legacy_gateways_filtered().await;
let nym_nodes = self.nym_contract_cache.nym_nodes_filtered().await;
// TODO: for the purposes of rewarding, this might have to grab some pre-filtered nodes instead,
// such as ones that use up to date version or have correct 'peanut' score
let nym_nodes = self.nym_contract_cache.nym_nodes().await;
if legacy_mixnodes.is_empty() && legacy_gateways.is_empty() && nym_nodes.is_empty() {
// that's a bit weird, but ok
@@ -539,14 +539,14 @@ impl PacketPreparer {
if let Some(rewarded_set) = rewarded_set {
let mut rng = thread_rng();
for mix in mixing_nym_nodes {
if let Some(parsed) = self.nym_node_to_legacy_mix(&mut rng, &rewarded_set, &mix) {
if let Some(parsed) = self.nym_node_to_legacy_mix(&mut rng, &rewarded_set, mix) {
tested_mixnodes.push(TestableNode::from(&parsed));
}
}
}
for gateway in gateway_capable_nym_nodes {
if let Some(parsed) = self.nym_node_to_legacy_gateway(&gateway) {
if let Some(parsed) = self.nym_node_to_legacy_gateway(gateway) {
tested_gateways.push((&parsed, gateway.node_id).into())
}
}
-8
View File
@@ -456,11 +456,3 @@ impl NymApiStorageError {
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn uptime_response_conversion() {}
}
+2 -4
View File
@@ -69,6 +69,7 @@ impl NymContractCache {
}
}
#[allow(clippy::too_many_arguments)]
pub(crate) async fn update(
&self,
mixnodes: Vec<LegacyMixNodeDetailsWithLayer>,
@@ -182,6 +183,7 @@ impl NymContractCache {
.map(|g| g.owner.to_string())
}
#[allow(dead_code)]
pub async fn legacy_mixnode_owner(&self, node_id: NodeId) -> Option<String> {
self.get(|c| &c.legacy_mixnodes)
.await?
@@ -257,10 +259,6 @@ impl NymContractCache {
.into_inner()
}
pub async fn nym_nodes_filtered(&self) -> Vec<NymNodeDetails> {
todo!()
}
pub async fn rewarded_set(&self) -> Option<RwLockReadGuard<Cache<CachedRewardedSet>>> {
self.get(|cache| &cache.rewarded_set).await
}
+3 -3
View File
@@ -111,9 +111,9 @@ impl AppState {
// handler helpers to easily get data or return error response
impl AppState {
pub(crate) async fn describe_nodes_cache_data<'a>(
&'a self,
) -> Result<RwLockReadGuard<'a, Cache<DescribedNodes>>, AxumErrorResponse> {
pub(crate) async fn describe_nodes_cache_data(
&self,
) -> Result<RwLockReadGuard<Cache<DescribedNodes>>, AxumErrorResponse> {
Ok(self.described_nodes_cache().get().await?)
}
+70 -74
View File
@@ -10,7 +10,7 @@ use crate::support::storage::models::{
use nym_mixnet_contract_common::{EpochId, IdentityKey, NodeId};
use nym_types::monitoring::NodeResult;
use sqlx::FromRow;
use time::Date;
use time::{Date, OffsetDateTime};
use tracing::info;
#[derive(Clone)]
@@ -580,41 +580,39 @@ impl StorageManager {
) -> Result<(), sqlx::Error> {
info!("Inserting {} mixnode statuses", mixnode_results.len());
todo!("look at what broke during rebasing");
//
// let timestamp = OffsetDateTime::now_utc().unix_timestamp();
// // insert it all in a transaction to make sure all nodes are updated at the same time
// // (plus it's a nice guard against new nodes)
// let mut tx = self.connection_pool.begin().await?;
// for mixnode_result in mixnode_results {
// let mixnode_id = sqlx::query!(
// r#"
// INSERT OR IGNORE INTO mixnode_details_v2(node_id, identity_key) VALUES (?, ?);
// SELECT id FROM mixnode_details_v2 WHERE node_id = ?;
// "#,
// mixnode_result.node_id,
// mixnode_result.identity,
// mixnode_result.node_id,
// )
// .fetch_one(&mut tx)
// .await?
// .id;
//
// // insert the actual status
// sqlx::query!(
// r#"
// INSERT INTO mixnode_status_v2 (mixnode_details_id, reliability, timestamp) VALUES (?, ?, ?);
// "#,
// mixnode_id,
// mixnode_result.reliability,
// timestamp
// )
// .execute(&mut tx)
// .await?;
// }
//
// // finally commit the transaction
// tx.commit().await
let timestamp = OffsetDateTime::now_utc().unix_timestamp();
// insert it all in a transaction to make sure all nodes are updated at the same time
// (plus it's a nice guard against new nodes)
let mut tx = self.connection_pool.begin().await?;
for mixnode_result in mixnode_results {
let mixnode_id = sqlx::query!(
r#"
INSERT OR IGNORE INTO mixnode_details_v2(node_id, identity_key) VALUES (?, ?);
SELECT id FROM mixnode_details_v2 WHERE node_id = ?;
"#,
mixnode_result.node_id,
mixnode_result.identity,
mixnode_result.node_id,
)
.fetch_one(&mut tx)
.await?
.id;
// insert the actual status
sqlx::query!(
r#"
INSERT INTO mixnode_status_v2 (mixnode_details_id, reliability, timestamp) VALUES (?, ?, ?);
"#,
mixnode_id,
mixnode_result.reliability,
timestamp
)
.execute(&mut tx)
.await?;
}
// finally commit the transaction
tx.commit().await
}
/// Tries to submit gateway [`NodeResult`] from the network monitor to the database.
@@ -672,45 +670,43 @@ impl StorageManager {
) -> Result<(), sqlx::Error> {
info!("Inserting {} gateway statuses", gateway_results.len());
todo!("look at what broke during rebasing");
let timestamp = OffsetDateTime::now_utc().unix_timestamp();
// insert it all in a transaction to make sure all nodes are updated at the same time
// (plus it's a nice guard against new nodes)
let mut tx = self.connection_pool.begin().await?;
// let timestamp = OffsetDateTime::now_utc().unix_timestamp();
// // insert it all in a transaction to make sure all nodes are updated at the same time
// // (plus it's a nice guard against new nodes)
// let mut tx = self.connection_pool.begin().await?;
//
// for gateway_result in gateway_results {
// // if gateway info doesn't exist, insert it and get its id
//
// // same ID "problem" as described for mixnode insertion
// let gateway_id = sqlx::query!(
// r#"
// INSERT OR IGNORE INTO gateway_details_v2(identity, node_id) VALUES (?, ?);
// SELECT id FROM gateway_details_v2 WHERE identity = ?;
// "#,
// gateway_result.identity,
// gateway_result.node_id,
// gateway_result.identity,
// )
// .fetch_one(&mut tx)
// .await?
// .id;
//
// // insert the actual status
// sqlx::query!(
// r#"
// INSERT INTO gateway_status_v2 (gateway_details_id, reliability, timestamp) VALUES (?, ?, ?);
// "#,
// gateway_id,
// gateway_result.reliability,
// timestamp
// )
// .execute(&mut tx)
// .await?;
// }
//
// // finally commit the transaction
// tx.commit().await
for gateway_result in gateway_results {
// if gateway info doesn't exist, insert it and get its id
// same ID "problem" as described for mixnode insertion
let gateway_id = sqlx::query!(
r#"
INSERT OR IGNORE INTO gateway_details_v2(identity, node_id) VALUES (?, ?);
SELECT id FROM gateway_details_v2 WHERE identity = ?;
"#,
gateway_result.identity,
gateway_result.node_id,
gateway_result.identity,
)
.fetch_one(&mut tx)
.await?
.id;
// insert the actual status
sqlx::query!(
r#"
INSERT INTO gateway_status_v2 (gateway_details_id, reliability, timestamp) VALUES (?, ?, ?);
"#,
gateway_id,
gateway_result.reliability,
timestamp
)
.execute(&mut tx)
.await?;
}
// finally commit the transaction
tx.commit().await
}
/// Saves the information about which nodes were used as core nodes during this particular
+8 -12
View File
@@ -15,16 +15,16 @@ use utoipa::ToSchema;
use crate::{NYM_API_URL, PRIVATE_KEY, TOPOLOGY};
struct HydratedRoute {
mix_nodes: Vec<mix::Node>,
gateway_node: gateway::Node,
mix_nodes: Vec<mix::LegacyNode>,
gateway_node: gateway::LegacyNode,
}
#[derive(Serialize, Deserialize, Debug, Default, ToSchema)]
struct GatewayStats(u32, u32, Option<String>);
struct GatewayStats(u32, u32);
impl GatewayStats {
fn new(sent: u32, recv: u32, owner: Option<String>) -> Self {
GatewayStats(sent, recv, owner)
fn new(sent: u32, recv: u32) -> Self {
GatewayStats(sent, recv)
}
fn success(&self) -> u32 {
@@ -60,9 +60,9 @@ pub struct NetworkAccount {
topology: NymTopology,
tested_nodes: HashSet<u32>,
#[serde(skip)]
mix_details: HashMap<u32, mix::Node>,
mix_details: HashMap<u32, mix::LegacyNode>,
#[serde(skip)]
gateway_details: HashMap<String, gateway::Node>,
gateway_details: HashMap<String, gateway::LegacyNode>,
}
impl NetworkAccount {
@@ -82,7 +82,6 @@ impl NetworkAccount {
complete_routes,
incomplete_routes,
node.identity_key.to_base58_string(),
node.owner.clone(),
)
}
@@ -186,7 +185,7 @@ impl NetworkAccount {
let gateway_stats_entry = self
.gateway_stats
.entry(route.gateway_node.identity_key.to_base58_string())
.or_insert(GatewayStats::new(0, 0, route.gateway_node.owner.clone()));
.or_insert(GatewayStats::new(0, 0));
self.gateway_details.insert(
route.gateway_node.identity_key.to_base58_string(),
route.gateway_node,
@@ -265,7 +264,6 @@ pub struct NodeStats {
incomplete_routes: usize,
reliability: f64,
identity: String,
owner: Option<String>,
}
impl NodeStats {
@@ -274,7 +272,6 @@ impl NodeStats {
complete_routes: usize,
incomplete_routes: usize,
identity: String,
owner: Option<String>,
) -> Self {
NodeStats {
mix_id,
@@ -282,7 +279,6 @@ impl NodeStats {
incomplete_routes,
reliability: complete_routes as f64 / (complete_routes + incomplete_routes) as f64,
identity,
owner,
}
}
+10 -8
View File
@@ -167,9 +167,9 @@ checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545"
[[package]]
name = "async-trait"
version = "0.1.82"
version = "0.1.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1"
checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd"
dependencies = [
"proc-macro2",
"quote",
@@ -1631,9 +1631,9 @@ dependencies = [
[[package]]
name = "flate2"
version = "1.0.33"
version = "1.0.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253"
checksum = "a1b589b4dc103969ad3cf85c950899926ec64300a1a46d76c03a6072957036f0"
dependencies = [
"crc32fast",
"miniz_oxide 0.8.0",
@@ -3360,6 +3360,7 @@ version = "0.1.0"
dependencies = [
"base64 0.22.1",
"bs58",
"hex",
"serde",
"time",
]
@@ -3448,6 +3449,7 @@ dependencies = [
"nym-mixnet-contract-common",
"nym-multisig-contract-common",
"nym-network-defaults",
"nym-serde-helpers",
"nym-vesting-contract-common",
"prost",
"reqwest 0.12.4",
@@ -5760,18 +5762,18 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c"
[[package]]
name = "thiserror"
version = "1.0.63"
version = "1.0.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.63"
version = "1.0.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3"
dependencies = [
"proc-macro2",
"quote",
@@ -21,7 +21,6 @@ async fn main() {
1,
vec![mix::LegacyNode {
mix_id: 63,
owner: None,
host: "172.105.92.48".parse().unwrap(),
mix_host: "172.105.92.48:1789".parse().unwrap(),
identity_key: "GLdR2NRVZBiCoCbv4fNqt9wUJZAnNjGXHkx3TjVAUzrK"
@@ -38,7 +37,6 @@ async fn main() {
2,
vec![mix::LegacyNode {
mix_id: 23,
owner: None,
host: "178.79.143.65".parse().unwrap(),
mix_host: "178.79.143.65:1789".parse().unwrap(),
identity_key: "4Yr4qmEHd9sgsuQ83191FR2hD88RfsbMmB4tzhhZWriz"
@@ -55,7 +53,6 @@ async fn main() {
3,
vec![mix::LegacyNode {
mix_id: 66,
owner: None,
host: "139.162.247.97".parse().unwrap(),
mix_host: "139.162.247.97:1789".parse().unwrap(),
identity_key: "66UngapebhJRni3Nj52EW1qcNsWYiuonjkWJzHFsmyYY"
@@ -113,7 +113,7 @@ impl NetworkManager {
if let Some(node) = gateways
.nodes
.iter()
.find(|gw| &gw.ed25519_identity_pubkey == identity)
.find(|gw| &gw.ed25519_identity_pubkey.to_base58_string() == identity)
{
return SocketAddr::new(
node.ip_addresses[0],
@@ -9,7 +9,7 @@ use crate::manager::NetworkManager;
use console::style;
use nym_mixnet_contract_common::nym_node::Role;
use nym_mixnet_contract_common::RoleAssignment;
use nym_validator_client::nyxd::contract_traits::{MixnetQueryClient, MixnetSigningClient};
use nym_validator_client::nyxd::contract_traits::MixnetSigningClient;
use nym_validator_client::DirectSigningHttpRpcNyxdClient;
use serde::{Deserialize, Serialize};
use std::fs;
@@ -372,7 +372,7 @@ impl NetworkManager {
ctx: &LocalNodesCtx<'a>,
) -> Result<(), NetworkManagerError> {
ctx.println(format!(
"🔌 {}Assigning mixnodes to the active set...",
"🔌 {}Assigning nodes to the active set...",
style("[4/5]").bold().dim()
));
@@ -386,58 +386,17 @@ impl NetworkManager {
let fut = rewarder.reconcile_epoch_events(None, None);
ctx.async_with_progress(fut).await?;
ctx.set_pb_message("[BROKEN] finally assigning the active set...");
// let fut = rewarder.get_rewarding_parameters();
// let rewarding_params = ctx.async_with_progress(fut).await?;
// let active_set_size = rewarding_params.active_set_size;
let unused_variable = "this has to be fixed up and refactored....";
/*
fn generate_role_assignment_messages(
&self,
rewarded_set: RewardedSet,
) -> Vec<(ExecuteMsg, Vec<Coin>)> {
// currently we just assign all of them together,
// but the contract is ready to handle them separately should we need it
// if the tx is too big
let mut msgs = Vec::new();
for (role, nodes) in [
(Role::ExitGateway, rewarded_set.exit_gateways),
(Role::EntryGateway, rewarded_set.entry_gateways),
(Role::Layer1, rewarded_set.layer1),
(Role::Layer2, rewarded_set.layer2),
(Role::Layer3, rewarded_set.layer3),
(Role::Standby, rewarded_set.standby),
] {
msgs.push((
ExecuteMsg::AssignRoles {
assignment: RoleAssignment { role, nodes },
},
Vec::new(),
));
}
msgs
}
*/
ctx.set_pb_message("finally assigning the active set... entry...");
let fut = rewarder.assign_roles(
RoleAssignment {
role: Role::ExitGateway,
role: Role::EntryGateway,
nodes: vec![4],
},
None,
);
ctx.async_with_progress(fut).await?;
let fut = rewarder.assign_roles(
RoleAssignment {
role: Role::EntryGateway,
nodes: vec![],
},
None,
);
ctx.async_with_progress(fut).await?;
ctx.set_pb_message("finally assigning the active set... layer1...");
let fut = rewarder.assign_roles(
RoleAssignment {
role: Role::Layer1,
@@ -447,6 +406,7 @@ impl NetworkManager {
);
ctx.async_with_progress(fut).await?;
ctx.set_pb_message("finally assigning the active set... layer2...");
let fut = rewarder.assign_roles(
RoleAssignment {
role: Role::Layer2,
@@ -456,6 +416,7 @@ impl NetworkManager {
);
ctx.async_with_progress(fut).await?;
ctx.set_pb_message("finally assigning the active set... layer3...");
let fut = rewarder.assign_roles(
RoleAssignment {
role: Role::Layer3,
@@ -465,6 +426,7 @@ impl NetworkManager {
);
ctx.async_with_progress(fut).await?;
ctx.set_pb_message("finally assigning the active set... [empty] standby...");
let fut = rewarder.assign_roles(
RoleAssignment {
role: Role::Standby,