Revert "chore: workspace global panic preventing lints (#5512)"

This reverts commit 6ac6747cc7.
This commit is contained in:
Jędrzej Stuczyński
2025-02-26 10:30:22 +00:00
committed by GitHub
parent 6ac6747cc7
commit 308de3a7cb
48 changed files with 77 additions and 221 deletions
Generated
+1 -1
View File
@@ -6273,7 +6273,7 @@ dependencies = [
[[package]]
name = "nym-node-status-agent"
version = "1.0.0-rc.2"
version = "1.0.0-rc.1"
dependencies = [
"anyhow",
"clap",
-10
View File
@@ -437,13 +437,3 @@ opt-level = 'z'
[profile.release.package.mix-fetch-wasm]
# lto = true
opt-level = 'z'
[workspace.lints.clippy]
unwrap_used = "deny"
expect_used = "deny"
todo = "deny"
dbg_macro = "deny"
exit = "deny"
panic = "deny"
unimplemented = "deny"
unreachable = "deny"
-1
View File
@@ -1,3 +1,2 @@
allow-unwrap-in-tests = true
allow-expect-in-tests = true
allow-panic-in-tests = true
+1 -4
View File
@@ -43,7 +43,4 @@ serde = ["dep:serde", "serde_bytes", "ed25519-dalek/serde", "x25519-dalek/serde"
asymmetric = ["x25519-dalek", "ed25519-dalek", "zeroize"]
hashing = ["blake3", "digest", "hkdf", "hmac", "generic-array", "sha2"]
stream_cipher = ["aes", "ctr", "cipher", "generic-array"]
sphinx = ["nym-sphinx-types/sphinx"]
[lints]
workspace = true
sphinx = ["nym-sphinx-types/sphinx"]
+4 -10
View File
@@ -16,11 +16,8 @@ pub fn compute_keyed_hmac<D>(key: &[u8], data: &[u8]) -> HmacOutput<D>
where
D: Digest + BlockSizeUser,
{
// SAFETY: hmac is fine with keys of any size; if they're smaller than the block size of the underlying
// digest, they're padded with 0. if they're larger they're hashed and padded
// the reason for `Result` return type is due to the trait definition
#[allow(clippy::unwrap_used)]
let mut hmac = SimpleHmac::<D>::new_from_slice(key).unwrap();
let mut hmac = SimpleHmac::<D>::new_from_slice(key)
.expect("HMAC was instantiated with a key of an invalid size!");
hmac.update(data);
hmac.finalize()
}
@@ -30,11 +27,8 @@ pub fn recompute_keyed_hmac_and_verify_tag<D>(key: &[u8], data: &[u8], tag: &[u8
where
D: Digest + BlockSizeUser,
{
// SAFETY: hmac is fine with keys of any size; if they're smaller than the block size of the underlying
// digest, they're padded with 0. if they're larger they're hashed and padded
// the reason for `Result` return type is due to the trait definition
#[allow(clippy::unwrap_used)]
let mut hmac = SimpleHmac::<D>::new_from_slice(key).unwrap();
let mut hmac = SimpleHmac::<D>::new_from_slice(key)
.expect("HMAC was instantiated with a key of an invalid size!");
hmac.update(data);
let tag_arr = Output::<D>::from_slice(tag);
+5 -14
View File
@@ -27,16 +27,12 @@ where
// after performing diffie-hellman we don't care about the private component anymore
let dh_result = ephemeral_keypair.private_key().diffie_hellman(remote_key);
// SAFETY: while this is a relatively weak assumption, it's unlikely that any stream cipher has `C::key_size()`
// larger than 255 * chunk_size of the digest (so for example keys larger than 8160 bytes if sh256 is used)
#[allow(clippy::expect_used)]
// there is no reason for this to fail as our okm is expected to be only C::KeySize bytes
let okm = hkdf::extract_then_expand::<D>(None, &dh_result, None, C::key_size())
.expect("somehow too long okm was provided");
// SAFETY: the generated okm has exactly `C::key_size()` elements,
// so this call is safe
#[allow(clippy::unwrap_used)]
let derived_shared_key = Key::<C>::from_exact_iter(okm).unwrap();
let derived_shared_key =
Key::<C>::from_exact_iter(okm).expect("okm was expanded to incorrect length!");
(ephemeral_keypair, derived_shared_key)
}
@@ -52,14 +48,9 @@ where
{
let dh_result = local_key.diffie_hellman(remote_key);
// SAFETY: while this is a relatively weak assumption, it's unlikely that any stream cipher has `C::key_size()`
// larger than 255 * chunk_size of the digest (so for example keys larger than 8160 bytes if sh256 is used)
#[allow(clippy::expect_used)]
// there is no reason for this to fail as our okm is expected to be only C::KeySize bytes
let okm = hkdf::extract_then_expand::<D>(None, &dh_result, None, C::key_size())
.expect("somehow too long okm was provided");
// SAFETY: the generated okm has exactly `C::key_size()` elements,
// so this call is safe
#[allow(clippy::unwrap_used)]
Key::<C>::from_exact_iter(okm).unwrap()
Key::<C>::from_exact_iter(okm).expect("okm was expanded to incorrect length!")
}
+9 -4
View File
@@ -60,15 +60,20 @@ where
Iv::<C>::default()
}
pub fn try_iv_from_slice<C>(b: &[u8]) -> Option<&IV<C>>
pub fn iv_from_slice<C>(b: &[u8]) -> &IV<C>
where
C: IvSizeUser,
{
if b.len() != C::iv_size() {
None
} else {
Some(IV::<C>::from_slice(b))
// `from_slice` would have caused a panic about this issue anyway.
// Now we at least have slightly more information
panic!(
"Tried to convert {} bytes to IV. Expected {}",
b.len(),
C::iv_size()
)
}
IV::<C>::from_slice(b)
}
// TODO: there's really no way to use more parts of the keystream if it was required at some point.
@@ -2,9 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
use crate::AckKey;
use nym_crypto::symmetric::stream_cipher::{
self, encrypt, random_iv, try_iv_from_slice, IvSizeUser,
};
use nym_crypto::symmetric::stream_cipher::{self, encrypt, iv_from_slice, random_iv, IvSizeUser};
use nym_sphinx_params::{AckEncryptionAlgorithm, SerializedFragmentIdentifier, FRAG_ID_LEN};
use rand::{CryptoRng, RngCore};
@@ -27,11 +25,7 @@ pub fn recover_identifier(
iv_id_ciphertext: &[u8],
) -> Option<SerializedFragmentIdentifier> {
let iv_size = AckEncryptionAlgorithm::iv_size();
if iv_id_ciphertext.len() < FRAG_ID_LEN + iv_size {
return None;
}
let iv = try_iv_from_slice::<AckEncryptionAlgorithm>(&iv_id_ciphertext[..iv_size])?;
let iv = iv_from_slice::<AckEncryptionAlgorithm>(&iv_id_ciphertext[..iv_size]);
let id = stream_cipher::decrypt::<AckEncryptionAlgorithm>(
key.inner(),
-7
View File
@@ -1,7 +0,0 @@
{
"git": {
"deploymentEnabled": {
"master": false
}
}
}
-3
View File
@@ -141,6 +141,3 @@ cw3 = { workspace = true }
cw-utils = { workspace = true }
rand_chacha = { workspace = true }
sha2 = "0.9"
[lints]
workspace = true
-3
View File
@@ -1,9 +1,6 @@
use sqlx::{Connection, FromRow, SqliteConnection};
use std::env;
// it's fine if compilation fails
#[allow(clippy::unwrap_used)]
#[allow(clippy::expect_used)]
#[tokio::main]
async fn main() {
let out_dir = env::var("OUT_DIR").unwrap();
+1 -3
View File
@@ -47,8 +47,6 @@ impl CachedEpoch {
let now = OffsetDateTime::now_utc();
let validity_duration = if let Some(epoch_finish) = epoch.deadline {
// SAFETY: values set in our contract are valid unix timestamps
#[allow(clippy::unwrap_used)]
let state_end =
OffsetDateTime::from_unix_timestamp(epoch_finish.seconds() as i64).unwrap();
let until_epoch_state_end = state_end - now;
@@ -105,7 +103,7 @@ impl APICommunicationChannel for QueryCommunicationChannel {
drop(guard);
let guard = self.update_epoch_cache().await?;
Ok(guard.current_epoch.epoch_id)
return Ok(guard.current_epoch.epoch_id);
}
// TODO: perhaps this should be returning a ReadGuard instead?
+1 -4
View File
@@ -189,10 +189,7 @@ impl<R: RngCore + CryptoRng + Clone> DkgController<R> {
self.state.clear_previous_epoch(epoch_id);
// SAFETY: we just accessed this item in an immutable way, thus it MUST exist so the unwrap is fine
#[allow(clippy::unwrap_used)]
{
self.state.in_progress_state_mut(epoch_id).unwrap().entered = true;
}
self.state.in_progress_state_mut(epoch_id).unwrap().entered = true;
}
// so at this point we don't need to be polling the contract so often anymore, but we can't easily
+1 -2
View File
@@ -204,9 +204,8 @@ impl<R: RngCore + CryptoRng> DkgController<R> {
chunk_dealing(*dealing_index, dealing.to_bytes(), Self::DEALING_CHUNK_SIZE);
for chunk_index in needs_resubmission {
// this is a hard failure, panic level, actually.
// because we have already committed to dealings of particular size,
// because we have already committed to dealings of particular size
// yet we don't have relevant chunks after chunking
#[allow(clippy::expect_used)]
let chunk = chunks
.remove(chunk_index)
.expect("chunking specification has changed mid-exchange!");
-4
View File
@@ -177,8 +177,6 @@ impl<R: RngCore + CryptoRng> DkgController<R> {
// SAFETY:
// since this share appears as 'verified' on the chain, it means the consensus of dealers confirmed its validity
// and thus they must have been able to parse it, so the unwrap/expect here is fine
// (unless quorum of validators is malicious, but at that point we have bigger problems...)
#[allow(clippy::expect_used)]
Ok(Some(
VerificationKeyAuth::try_from_bs58(&share.share)
.expect("failed to deserialize VERIFIED key"),
@@ -417,7 +415,6 @@ impl<R: RngCore + CryptoRng> DkgController<R> {
// SAFETY: combining shares can only fail if we have different number shares and indices
// however, we returned an explicit error if decryption of any share failed and thus we know those values must match
#[allow(clippy::unwrap_used)]
let secret = combine_shares(shares, &all_dealers).unwrap();
if derived_x.is_none() {
derived_x = Some(secret)
@@ -429,7 +426,6 @@ impl<R: RngCore + CryptoRng> DkgController<R> {
// SAFETY:
// we know we had a non-empty map of dealings and thus, at the very least, we must have derived a single secret
// (i.e. the x-element)
#[allow(clippy::unwrap_used)]
let sk = SecretKeyAuth::create_from_raw(derived_x.unwrap(), derived_secrets);
let derived_vk = sk.verification_key();
+2 -3
View File
@@ -140,9 +140,6 @@ impl EcashState {
}
}
// whilst we normally don't want to panic, this one would only occur at startup,
// if some logical invariants got broken (which have to be fixed in code anyway)
#[allow(clippy::panic)]
pub(crate) fn spawn_background_cleaner(&mut self) {
match std::mem::take(&mut self.background_cleaner_state) {
BackgroundCleanerState::WaitingStartup(cleaner) => {
@@ -150,6 +147,8 @@ impl EcashState {
_handle: cleaner.start(),
}
}
// whilst we normally don't want to panic, this one would only occur at startup,
// if some logical invariants got broken (which have to be fixed in code anyway)
_ => panic!("attempted to spawn background cleaner more than once"),
}
}
-6
View File
@@ -13,9 +13,6 @@ struct StorageBorrowedSerdeWrapper<'a, T>(&'a T);
#[derive(Serialize, Deserialize)]
struct StorageSerdeWrapper<T>(T);
// SAFETY: we're not using custom serialiser for AnnotatedCoinIndexSignature
// and we're within bound limits
#[allow(clippy::unwrap_used)]
pub(crate) fn serialise_coin_index_signatures(sigs: &[AnnotatedCoinIndexSignature]) -> Vec<u8> {
storage_serialiser()
.serialize(&StorageBorrowedSerdeWrapper(&sigs))
@@ -31,9 +28,6 @@ pub(crate) fn deserialise_coin_index_signatures(
Ok(de.0)
}
// SAFETY: we're not using custom serialiser for AnnotatedExpirationDateSignature
// and we're within bound limits
#[allow(clippy::unwrap_used)]
pub(crate) fn serialise_expiration_date_signatures(
sigs: &[AnnotatedExpirationDateSignature],
) -> Vec<u8> {
+10 -10
View File
@@ -428,27 +428,27 @@ impl FakeChainState {
);
let epoch_id = self.dkg_contract.epoch.epoch_id;
let Some(shares) = self.dkg_contract.verification_shares.get_mut(&epoch_id) else {
panic!("no shares for epoch")
unimplemented!("no shares for epoch")
};
let Some(share) = shares.get_mut(owner.as_str()) else {
panic!("no shares for owner")
unimplemented!("no shares for owner")
};
share.verified = true
}
other => panic!("unimplemented exec of {other:?}"),
other => unimplemented!("unimplemented exec of {other:?}"),
}
}
// TODO: make it return a result
fn execute_contract_msg(&mut self, contract: &String, msg: &Binary, sender: MessageInfo) {
if contract == &self.group_contract.address {
panic!("group contract exec")
unimplemented!("group contract exec")
}
if contract == &self.multisig_contract.address {
panic!("multisig contract exec")
unimplemented!("multisig contract exec")
}
if contract == &self.ecash_contract.address {
panic!("bandwidth contract exec")
unimplemented!("bandwidth contract exec")
}
if contract == self.dkg_contract.address.as_ref() {
return self.execute_dkg_contract(sender, msg);
@@ -467,7 +467,7 @@ impl FakeChainState {
let sender = mock_info(sender_address.as_ref(), funds);
self.execute_contract_msg(contract_addr, msg, sender)
}
other => panic!("unimplemented wasm proposal for {other:?}"),
other => unimplemented!("unimplemented wasm proposal for {other:?}"),
}
}
@@ -477,7 +477,7 @@ impl FakeChainState {
CosmosMsg::Wasm(wasm_msg) => {
self.execute_wasm_msg(wasm_msg, Addr::unchecked(sender_address.as_ref()))
}
other => panic!("unimplemented proposal for {other:?}"),
other => unimplemented!("unimplemented proposal for {other:?}"),
};
}
}
@@ -907,7 +907,7 @@ impl super::client::Client for DummyClient {
};
if proposal.status != cw3::Status::Passed {
panic!("proposal hasn't been passed")
unimplemented!("proposal hasn't been passed")
}
proposal.status = cw3::Status::Executed;
@@ -954,7 +954,7 @@ impl super::client::Client for DummyClient {
if !epoch_dealers.contains_key(self.validator_address.as_ref()) {
epoch_dealers.insert(self.validator_address.to_string(), dealer_details);
} else {
panic!("already registered")
unimplemented!("already registered")
}
let transaction_hash = guard._counters.next_tx_hash();
-3
View File
@@ -105,11 +105,8 @@ impl EpochAdvancer {
let standby_node_work_factor = global_rewarding_params.standby_node_work();
// SANITY CHECK:
// SAFETY: 0 decimal places is within the range of `Decimal`
#[allow(clippy::unwrap_used)]
let standby_share = Decimal::from_atomics(nodes.standby.len() as u128, 0).unwrap()
* standby_node_work_factor;
#[allow(clippy::unwrap_used)]
let active_share = Decimal::from_atomics(nodes.active_set_size() as u128, 0).unwrap()
* active_node_work_factor;
let total_work = standby_share + active_share;
@@ -139,7 +139,6 @@ impl EpochAdvancer {
let mut layer2 = Vec::new();
let mut layer3 = Vec::new();
#[allow(clippy::panic)]
for (i, mix) in mixnodes_vec.iter().enumerate() {
match i % 3 {
0 => layer1.push(*mix),
@@ -208,7 +207,6 @@ impl EpochAdvancer {
let mut with_performance = Vec::new();
// SAFETY: the cache MUST HAVE been initialised before now
#[allow(clippy::unwrap_used)]
let described_cache = self.described_cache.get().await.unwrap();
let Some(status_cache) = self.status_cache.node_annotations().await else {
@@ -229,8 +229,6 @@ impl<R: MessageReceiver + Send + Sync> Monitor<R> {
// ideally we would blacklist all nodes regardless of the result so we would not use them anymore
// however, currently we have huge imbalance of gateways to mixnodes so we might accidentally
// discard working gateway because it was paired with broken mixnode
// SAFETY: the results is subset of candidates so the entry must exist
#[allow(clippy::unwrap_used)]
if *results.get(&candidate.id()).unwrap() {
// if the path is fully working, blacklist those nodes so we wouldn't construct
// any other path through any of those nodes
@@ -157,7 +157,6 @@ impl PacketPreparer {
self.contract_cache.wait_for_initial_values().await;
self.described_cache.naive_wait_for_initial_values().await;
#[allow(clippy::expect_used)]
let described_nodes = self
.described_cache
.get()
@@ -375,7 +374,6 @@ impl PacketPreparer {
.collect::<Vec<_>>();
// the unwrap on `min()` is fine as we know the iterator is not empty
#[allow(clippy::unwrap_used)]
let most_available = *[
rand_l1.len(),
rand_l2.len(),
@@ -429,7 +427,6 @@ impl PacketPreparer {
// 1. the topology is definitely valid (otherwise we wouldn't be here)
// 2. the recipient is specified (by calling **mix**_tester)
// 3. the test message is not too long, i.e. when serialized it will fit in a single sphinx packet
#[allow(clippy::unwrap_used)]
let mix_packets = plaintexts
.into_iter()
.map(|p| tester.wrap_plaintext_data(p, &topology, None).unwrap())
@@ -495,7 +492,6 @@ impl PacketPreparer {
) -> PreparedPackets {
let (mixnodes, gateways) = self.all_legacy_mixnodes_and_gateways().await;
#[allow(clippy::expect_used)]
let descriptions = self
.described_cache
.get()
@@ -169,9 +169,6 @@ where
where
R: Sync + Send + 'static,
{
// this panic could only be triggered by incorrect startup sequence and shouldn't affect
// the binary beyond that
#[allow(clippy::expect_used)]
let mut receiver_task = self
.receiver_task
.take()
@@ -8,7 +8,7 @@ use futures::StreamExt;
use nym_crypto::asymmetric::identity;
use nym_gateway_client::{AcknowledgementReceiver, MixnetMessageReceiver};
use nym_task::TaskClient;
use tracing::{error, trace};
use tracing::trace;
pub(crate) type GatewayClientUpdateSender = mpsc::UnboundedSender<GatewayClientUpdate>;
pub(crate) type GatewayClientUpdateReceiver = mpsc::UnboundedReceiver<GatewayClientUpdate>;
@@ -52,9 +52,9 @@ impl PacketReceiver {
}
fn process_gateway_messages(&self, messages: GatewayMessages) {
if self.processor_sender.unbounded_send(messages).is_err() {
error!("packet processor seems to have crashed!")
}
self.processor_sender
.unbounded_send(messages)
.expect("packet processor seems to have crashed!");
}
pub(crate) async fn run(&mut self, mut shutdown: TaskClient) {
@@ -66,13 +66,7 @@ impl PacketReceiver {
}
// unwrap here is fine as it can only return a `None` if the PacketSender has died
// and if that was the case, then the entire monitor is already in an undefined state
update = self.clients_updater.next() => {
if let Some(update) = update {
self.process_gateway_update(update)
} else {
error!("UpdateHandler: Client stream ended!");
}
},
update = self.clients_updater.next() => self.process_gateway_update(update.unwrap()),
Some((_gateway_id, messages)) = self.gateways_reader.next() => {
self.process_gateway_messages(messages)
}
@@ -246,8 +246,6 @@ impl PacketSender {
trace!("Sending {} packets...", mix_packets.len());
if mix_packets.len() == 1 {
// SAFETY: we just explicitly checked we have 1 message
#[allow(clippy::unwrap_used)]
client.send_mix_packet(mix_packets.pop().unwrap()).await?;
} else {
client.batch_send_mix_packets(mix_packets).await?;
@@ -104,7 +104,6 @@ impl TestRoute {
// the unwrap here is fine as the failure can only occur due to serialization and we're not
// using any custom implementations
#[allow(clippy::unwrap_used)]
NymApiTestMessageExt::new(self.id, ROUTE_TESTING_TEST_NONCE)
.mix_plaintexts(mix, count as u32)
.unwrap()
-5
View File
@@ -125,8 +125,6 @@ impl TryFrom<i64> for Uptime {
impl From<Uptime> for Performance {
fn from(uptime: Uptime) -> Self {
// SAFETY: uptime has a valid range to be transformed into a `Performance`
#[allow(clippy::unwrap_used)]
Performance::from_percentage_value(uptime.0 as u64).unwrap()
}
}
@@ -483,9 +481,6 @@ pub enum NymApiStorageError {
// this one would never be returned to users since it's only possible on startup
#[error("failed to perform startup SQL migration - {0}")]
StartupMigrationFailure(#[from] sqlx::migrate::MigrateError),
#[error("{value} is not a valid unix timestamp")]
InvalidTimestampProvided { value: i64 },
}
impl From<sqlx::Error> for NymApiStorageError {
@@ -8,8 +8,7 @@ use crate::node_status_api::ONE_DAY;
use crate::storage::NymApiStorage;
use nym_task::{TaskClient, TaskManager};
use std::time::Duration;
use time::macros::time;
use time::{OffsetDateTime, PrimitiveDateTime};
use time::{OffsetDateTime, PrimitiveDateTime, Time};
use tokio::time::{interval_at, Instant};
use tracing::error;
use tracing::{info, trace, warn};
@@ -76,20 +75,18 @@ impl HistoricalUptimeUpdater {
// nodes update for different days
// the unwrap is fine as 23:00:00 is a valid time
let update_time = time!(23:00:00);
let update_time = Time::from_hms(23, 0, 0).unwrap();
let now = OffsetDateTime::now_utc();
// is the current time within 0:00 - 22:59:59 or 23:00 - 23:59:59 ?
let update_date = if now.hour() < 23 {
now.date()
} else {
// the unwrap is fine as (**PRESUMABLY**) we're not running this code in the year 9999
#[allow(clippy::unwrap_used)]
now.date().next_day().unwrap()
};
let update_datetime = PrimitiveDateTime::new(update_date, update_time).assume_utc();
// the unwrap here is fine as we're certain `update_datetime` is in the future and thus the
// resultant Duration is positive
#[allow(clippy::unwrap_used)]
let time_left: Duration = (update_datetime - now).try_into().unwrap();
info!(
-1
View File
@@ -109,7 +109,6 @@ impl NodeUptimes {
// the unwraps in Uptime::from_ratio are fine because it's impossible for us to have more "up" results
// than total test runs as we just bounded them
#[allow(clippy::unwrap_used)]
NodeUptimes {
most_recent: most_recent.try_into().unwrap(),
last_hour: Uptime::from_uptime_sum(last_hour_sum, last_hour_test_runs).unwrap(),
-1
View File
@@ -128,7 +128,6 @@ impl NymContractCacheRefresher {
.collect();
let mut gateways = Vec::with_capacity(gateway_bonds.len());
#[allow(clippy::panic)]
for bond in gateway_bonds {
// we explicitly panic here because that value MUST exist.
// if it doesn't, we messed up the migration and we have big problems
@@ -47,8 +47,5 @@ impl LegacyAnnotation for GatewayBondAnnotated {
pub(crate) fn refreshed_at(
iter: impl IntoIterator<Item = OffsetDateTime>,
) -> OffsetDateTimeJsonSchemaWrapper {
iter.into_iter()
.min()
.unwrap_or(OffsetDateTime::UNIX_EPOCH)
.into()
iter.into_iter().min().unwrap().into()
}
+1 -1
View File
@@ -108,7 +108,7 @@ pub(crate) struct Args {
async fn start_nym_api_tasks_axum(config: &Config) -> anyhow::Result<ShutdownHandles> {
let task_manager = TaskManager::new(TASK_MANAGER_TIMEOUT_S);
let nyxd_client = nyxd::Client::new(config)?;
let nyxd_client = nyxd::Client::new(config);
let connected_nyxd = config.get_nyxd_url();
let nym_network_details = NymNetworkDetails::new_from_env();
let network_details = NetworkDetails::new(connected_nyxd.to_string(), nym_network_details);
-2
View File
@@ -268,8 +268,6 @@ pub struct Base {
impl Base {
pub fn new_default<S: Into<String>>(id: S) -> Self {
// SAFETY: the provided hardcoded value is well-formed
#[allow(clippy::expect_used)]
let default_validator: Url = DEFAULT_LOCAL_VALIDATOR
.parse()
.expect("default local validator is malformed!");
+8 -9
View File
@@ -4,7 +4,7 @@
use crate::ecash::error::EcashError;
use crate::epoch_operations::RewardedNodeWithParams;
use crate::support::config::Config;
use anyhow::{Context, Result};
use anyhow::Result;
use async_trait::async_trait;
use cw3::{ProposalResponse, VoteResponse};
use cw4::MemberResponse;
@@ -99,13 +99,12 @@ pub enum ClientInner {
}
impl Client {
pub(crate) fn new(config: &Config) -> anyhow::Result<Self> {
pub(crate) fn new(config: &Config) -> Self {
let details = NymNetworkDetails::new_from_env();
let nyxd_url = config.get_nyxd_url();
let client_config = nyxd::Config::try_from_nym_network_details(&details).context(
"failed to construct valid validator client config with the provided network",
)?;
let client_config = nyxd::Config::try_from_nym_network_details(&details)
.expect("failed to construct valid validator client config with the provided network");
let inner = if let Some(mnemonic) = config.get_mnemonic() {
ClientInner::Signing(
@@ -114,18 +113,18 @@ impl Client {
nyxd_url.as_str(),
mnemonic.clone(),
)
.context("Failed to connect to nyxd!")?,
.expect("Failed to connect to nyxd!"),
)
} else {
ClientInner::Query(
QueryHttpRpcNyxdClient::connect(client_config, nyxd_url.as_str())
.context("Failed to connect to nyxd!")?,
.expect("Failed to connect to nyxd!"),
)
};
Ok(Client {
Client {
inner: Arc::new(RwLock::new(inner)),
})
}
}
pub(crate) async fn read(&self) -> RwLockReadGuard<'_, ClientInner> {
+16 -19
View File
@@ -225,9 +225,9 @@ impl NymApiStorage {
.get_monitor_runs_count(day_ago, now.unix_timestamp())
.await?;
let Some(mixnode_identity) = self.manager.get_mixnode_identity_key(mix_id).await? else {
return Err(NymApiStorageError::DatabaseInconsistency { reason: format!("The node {mix_id} doesn't have an identity even though we have status information on it!") });
};
let mixnode_identity = self.manager.get_mixnode_identity_key(mix_id).await?.expect(
"The node doesn't have an identity even though we have status information on it!",
);
Ok(MixnodeStatusReport::construct_from_last_day_reports(
now,
@@ -262,9 +262,13 @@ impl NymApiStorage {
.get_monitor_runs_count(day_ago, now.unix_timestamp())
.await?;
let Some(gateway_identity) = self.manager.get_gateway_identity_key(node_id).await? else {
return Err(NymApiStorageError::DatabaseInconsistency { reason: format!("The node {node_id} doesn't have an identity even though we have status information on it!") });
};
let gateway_identity = self
.manager
.get_gateway_identity_key(node_id)
.await?
.expect(
"The node doesn't have an identity even though we have status information on it!",
);
Ok(GatewayStatusReport::construct_from_last_day_reports(
now,
@@ -286,9 +290,10 @@ impl NymApiStorage {
return Err(NymApiStorageError::MixnodeUptimeHistoryNotFound { mix_id });
}
let Some(mixnode_identity) = self.manager.get_mixnode_identity_key(mix_id).await? else {
return Err(NymApiStorageError::DatabaseInconsistency { reason: format!("The node {mix_id} doesn't have an identity even though we uptime history for it!") });
};
let mixnode_identity =
self.manager.get_mixnode_identity_key(mix_id).await?.expect(
"The node doesn't have an identity even though we have uptime history for it!",
);
Ok(MixnodeUptimeHistory::new(mix_id, mixnode_identity, history))
}
@@ -531,10 +536,6 @@ impl NymApiStorage {
start: i64,
end: i64,
) -> Result<Vec<MixnodeStatusReport>, NymApiStorageError> {
let Ok(end_timestamp) = OffsetDateTime::from_unix_timestamp(end) else {
return Err(NymApiStorageError::InvalidTimestampProvided { value: end });
};
if (end - start) as u64 != ONE_DAY.as_secs() {
warn!("Our current interval length breaks the 24h length assumption")
}
@@ -552,7 +553,7 @@ impl NymApiStorage {
.into_iter()
.map(|statuses| {
MixnodeStatusReport::construct_from_last_day_reports(
end_timestamp,
OffsetDateTime::from_unix_timestamp(end).unwrap(),
statuses.mix_id,
statuses.identity,
statuses.statuses,
@@ -578,10 +579,6 @@ impl NymApiStorage {
start: i64,
end: i64,
) -> Result<Vec<GatewayStatusReport>, NymApiStorageError> {
let Ok(end_timestamp) = OffsetDateTime::from_unix_timestamp(end) else {
return Err(NymApiStorageError::InvalidTimestampProvided { value: end });
};
if (end - start) as u64 != ONE_DAY.as_secs() {
warn!("Our current interval length breaks the 24h length assumption")
}
@@ -599,7 +596,7 @@ impl NymApiStorage {
.into_iter()
.map(|statuses| {
GatewayStatusReport::construct_from_last_day_reports(
end_timestamp,
OffsetDateTime::from_unix_timestamp(end).unwrap(),
statuses.node_id,
statuses.identity,
statuses.statuses,
@@ -3,7 +3,7 @@
[package]
name = "nym-node-status-agent"
version = "1.0.0-rc.2"
version = "1.0.0-rc.1"
authors.workspace = true
repository.workspace = true
homepage.workspace = true
@@ -1,9 +1,9 @@
#!/bin/bash
set -eu
export ENVIRONMENT=${ENVIRONMENT:-"mainnet"}
export ENVIRONMENT=${ENVIRONMENT:-"sandbox"}
probe_git_ref="nym-vpn-core-v1.3.2"
probe_git_ref="nym-vpn-core-v1.1.0"
crate_root=$(dirname $(realpath "$0"))
monorepo_root=$(realpath "${crate_root}/../..")
@@ -21,7 +21,6 @@ export NODE_STATUS_AGENT_SERVER_ADDRESS="http://127.0.0.1"
export NODE_STATUS_AGENT_SERVER_PORT="8000"
export NODE_STATUS_AGENT_PROBE_PATH="$crate_root/nym-gateway-probe"
export NODE_STATUS_AGENT_AUTH_KEY="BjyC9SsHAZUzPRkQR4sPTvVrp4GgaquTh5YfSJksvvWT"
export NODE_STATUS_AGENT_PROBE_EXTRA_ARGS="netstack-download-timeout-sec=30,netstack-num-ping=2,netstack-send-timeout-sec=1,netstack-recv-timeout-sec=1"
workers=${1:-1}
echo "Running $workers workers in parallel"
@@ -55,7 +54,7 @@ function swarm() {
echo "All agents completed"
}
copy_gw_probe
# copy_gw_probe
build_agent
swarm $workers
@@ -35,13 +35,6 @@ pub(crate) enum Command {
/// path of binary to run
#[arg(long, env = "NODE_STATUS_AGENT_PROBE_PATH")]
probe_path: String,
#[arg(
long,
env = "NODE_STATUS_AGENT_PROBE_EXTRA_ARGS",
value_delimiter = ','
)]
probe_extra_args: Vec<String>,
},
GenerateKeypair {
@@ -58,13 +51,11 @@ impl Args {
server_port,
ns_api_auth_key,
probe_path,
probe_extra_args,
} => run_probe::run_probe(
server_address,
server_port.to_owned(),
ns_api_auth_key,
probe_path,
probe_extra_args,
)
.await
.inspect_err(|err| {
@@ -7,7 +7,6 @@ pub(crate) async fn run_probe(
server_port: u16,
ns_api_auth_key: &str,
probe_path: &str,
probe_extra_args: &Vec<String>,
) -> anyhow::Result<()> {
let auth_key = PrivateKey::from_base58_string(ns_api_auth_key)
.context("Couldn't parse auth key, exiting")?;
@@ -20,7 +19,7 @@ pub(crate) async fn run_probe(
tracing::info!("Probe version:\n{}", version);
if let Some(testrun) = ns_api_client.request_testrun().await? {
let log = probe.run_and_get_log(&Some(testrun.gateway_identity_key), probe_extra_args);
let log = probe.run_and_get_log(&Some(testrun.gateway_identity_key));
ns_api_client
.submit_results(testrun.testrun_id, log, testrun.assigned_at_utc)
@@ -29,11 +29,7 @@ impl GwProbe {
}
}
pub(crate) fn run_and_get_log(
&self,
gateway_key: &Option<String>,
probe_extra_args: &Vec<String>,
) -> String {
pub(crate) fn run_and_get_log(&self, gateway_key: &Option<String>) -> String {
let mut command = std::process::Command::new(&self.path);
command.stdout(std::process::Stdio::piped());
@@ -41,16 +37,6 @@ impl GwProbe {
command.arg("--gateway").arg(gateway_id);
}
tracing::info!("Extra args for the probe:");
for arg in probe_extra_args {
let mut split = arg.splitn(2, '=');
let name = split.next().unwrap_or_default();
let value = split.next().unwrap_or_default();
tracing::info!("{} {}", name, value);
command.arg(format!("--{name}")).arg(value);
}
match command.spawn() {
Ok(child) => {
if let Ok(output) = child.wait_with_output() {
@@ -3,7 +3,7 @@
set -e
user_rust_log_preference=$RUST_LOG
export ENVIRONMENT=${ENVIRONMENT:-"mainnet"}
export ENVIRONMENT=${ENVIRONMENT:-"sandbox"}
export NYM_API_CLIENT_TIMEOUT=60
export EXPLORER_CLIENT_TIMEOUT=60
export NODE_STATUS_API_TESTRUN_REFRESH_INTERVAL=120
-4
View File
@@ -98,7 +98,3 @@ nym-ip-packet-router = { path = "../service-providers/ip-packet-router" }
[build-dependencies]
# temporary bonding information v1 (to grab and parse nym-mixnode and nym-gateway package versions)
cargo_metadata = { workspace = true }
[lints]
workspace = true
-2
View File
@@ -68,8 +68,6 @@ fn print_signed_contract_msg(
println!("{}", output.format(&sign_output));
}
// SAFETY: clippy ArgGroup ensures only a single branch is actually called
#[allow(clippy::unreachable)]
pub async fn execute(args: Args) -> Result<(), NymNodeError> {
let config = try_load_current_config(args.config.config_path()).await?;
let identity_keypair =
-3
View File
@@ -45,9 +45,6 @@ impl MetricsAggregator {
self.event_sender.clone()
}
// we must panic here to terminate as soon as possible, because the underlying code
// has to be resolved as it implies some serious logic bugs
#[allow(clippy::panic)]
pub fn register_handler<H>(&mut self, handler: H, update_interval: impl Into<Option<Duration>>)
where
H: MetricsHandler,
@@ -226,8 +226,6 @@ impl OnUpdateMetricsHandler for PrometheusGlobalNodeMetricsRegistryUpdater {
impl MetricsHandler for PrometheusGlobalNodeMetricsRegistryUpdater {
type Events = GlobalPrometheusData;
// SAFETY: `PrometheusNodeMetricsRegistryUpdater` doesn't have any associated events
#[allow(clippy::panic)]
async fn handle_event(&mut self, _event: Self::Events) {
panic!("this should have never been called! MetricsHandler has been incorrectly called on PrometheusNodeMetricsRegistryUpdater")
}
@@ -62,8 +62,6 @@ impl OnUpdateMetricsHandler for LegacyMixingStatsUpdater {
impl MetricsHandler for LegacyMixingStatsUpdater {
type Events = LegacyMixingData;
// SAFETY: `LegacyMixingStatsUpdater` doesn't have any associated events
#[allow(clippy::panic)]
async fn handle_event(&mut self, _event: Self::Events) {
panic!("this should have never been called! MetricsHandler has been incorrectly called on LegacyMixingStatsUpdater")
}
@@ -101,8 +101,6 @@ impl OnUpdateMetricsHandler for MixnetMetricsCleaner {
impl MetricsHandler for MixnetMetricsCleaner {
type Events = StaleMixnetMetrics;
// SAFETY: `MixnetMetricsCleaner` doesn't have any associated events
#[allow(clippy::panic)]
async fn handle_event(&mut self, _event: Self::Events) {
panic!("this should have never been called! MetricsHandler has been incorrectly called on MixnetMetricsCleaner")
}
@@ -54,8 +54,6 @@ impl OnUpdateMetricsHandler for PendingEgressPacketsUpdater {
impl MetricsHandler for PendingEgressPacketsUpdater {
type Events = PendingEgressPackets;
// SAFETY: `PendingEgressPacketsUpdater` doesn't have any associated events
#[allow(clippy::panic)]
async fn handle_event(&mut self, _event: Self::Events) {
panic!("this should have never been called! MetricsHandler has been incorrectly called on PendingEgressPacketsUpdater")
}