Compare commits

..

8 Commits

Author SHA1 Message Date
RadekSabacky 191240da2e + basepath env into image src 2025-07-08 13:48:08 +02:00
RadekSabacky 68ddf095b4 / remove /explorer from image src 2025-07-08 12:47:25 +02:00
RadekSabacky e873121cc2 / base path as env variable 2025-07-08 12:38:49 +02:00
Jack Wampler a7b57d7e58 Make Mix hops optional for Mixnet Client SURBs (#5861)
* allow SURBs to be configured without mix hops

* gateways require consistency in surb format so if disabling mixnhops - use updated format
2025-07-03 09:21:50 -06:00
benedettadavico 84e10a654c Revert "Bump ns-api version"
This reverts commit d724f94319.
2025-07-01 15:26:55 +02:00
benedetta davico d724f94319 Bump ns-api version 2025-07-01 15:19:56 +02:00
Jędrzej Stuczyński d0692a567a feat: basic performance contract integration [within Nym API] (#5871)
* renamed nym-api config fields

* decouple rewarder startup from network monitor

* additional sections in nym-api config

* removed vesting queries in circulating supply calculator

* added memoized field for last submitted performance measurement

* wip: performance contract refresher

* cleaned up various contract caches

* modified cache refresher to allow passing update fn

* implement performance cache refreshing

* updated lefthook.yml to run cargo fmt

* impl NodePerformanceProvider trait

* dynamically using specific performance provider

* pre warm up performance contract cache and forbid the mode if its empty

* clippy

* introduce fallback setting for performance contract if value for given epoch is not available

* move some functions around
2025-07-01 11:29:50 +01:00
Jędrzej Stuczyński 2ae38b9e49 chore: 1.88 clippy (#5877)
* 1.88 clippy

* wasm clippy

* wallet clippy
2025-07-01 10:28:57 +01:00
252 changed files with 5286 additions and 2083 deletions
Generated
+2
View File
@@ -6135,6 +6135,7 @@ dependencies = [
"futures", "futures",
"mime", "mime",
"serde", "serde",
"serde_json",
"serde_yaml", "serde_yaml",
"subtle 2.6.1", "subtle 2.6.1",
"time", "time",
@@ -6998,6 +6999,7 @@ dependencies = [
"tap", "tap",
"tempfile", "tempfile",
"thiserror 2.0.12", "thiserror 2.0.12",
"time",
"tokio", "tokio",
"tokio-stream", "tokio-stream",
"tokio-util", "tokio-util",
+1 -1
View File
@@ -318,7 +318,7 @@ impl Handler {
async fn handle_text_message(&mut self, msg: String) -> Option<WsMessage> { async fn handle_text_message(&mut self, msg: String) -> Option<WsMessage> {
debug!("Handling text message request"); debug!("Handling text message request");
trace!("Content: {:?}", msg); trace!("Content: {msg:?}");
self.received_response_type = ReceivedResponseType::Text; self.received_response_type = ReceivedResponseType::Text;
let client_request = ClientRequest::try_from_text(msg); let client_request = ClientRequest::try_from_text(msg);
+2 -2
View File
@@ -68,9 +68,9 @@ impl Listener {
new_conn = tcp_listener.accept() => { new_conn = tcp_listener.accept() => {
match new_conn { match new_conn {
Ok((mut socket, remote_addr)) => { Ok((mut socket, remote_addr)) => {
debug!("Received connection from {:?}", remote_addr); debug!("Received connection from {remote_addr:?}");
if self.state.is_connected() { if self.state.is_connected() {
warn!("Tried to open a duplicate websocket connection. The request came from {}", remote_addr); warn!("Tried to open a duplicate websocket connection. The request came from {remote_addr}");
// if we've already got a connection, don't allow another one // if we've already got a connection, don't allow another one
// while we only ever want to accept a single connection, we don't want // while we only ever want to accept a single connection, we don't want
// to leave clients hanging (and also allow for reconnection if it somehow // to leave clients hanging (and also allow for reconnection if it somehow
+1 -1
View File
@@ -137,7 +137,7 @@ impl AsyncFileWatcher {
log::error!("the file watcher receiver has been dropped!"); log::error!("the file watcher receiver has been dropped!");
} }
} else { } else {
log::debug!("will not propagate information about {:?}", event); log::debug!("will not propagate information about {event:?}");
} }
} }
Err(err) => { Err(err) => {
+1 -1
View File
@@ -11,7 +11,7 @@ impl std::fmt::Display for BandwidthStatusMessage {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
BandwidthStatusMessage::RemainingBandwidth(b) => { BandwidthStatusMessage::RemainingBandwidth(b) => {
write!(f, "remaining bandwidth: {}", b) write!(f, "remaining bandwidth: {b}")
} }
BandwidthStatusMessage::NoBandwidth => write!(f, "no bandwidth left"), BandwidthStatusMessage::NoBandwidth => write!(f, "no bandwidth left"),
} }
@@ -418,6 +418,9 @@ pub struct Traffic {
/// will be routed as usual, to the entry gateway, through three mix nodes, egressing /// will be routed as usual, to the entry gateway, through three mix nodes, egressing
/// through the exit gateway. If mix hops are disabled, traffic will be routed directly /// through the exit gateway. If mix hops are disabled, traffic will be routed directly
/// from the entry gateway to the exit gateway, bypassing the mix nodes. /// from the entry gateway to the exit gateway, bypassing the mix nodes.
///
/// This overrides the `use_legacy_sphinx_format` setting as reduced mix hops
/// requires use of the updated SURB packet format.
pub disable_mix_hops: bool, pub disable_mix_hops: bool,
} }
@@ -146,7 +146,7 @@ impl MixTrafficController {
Some(client_request) => { Some(client_request) => {
match self.gateway_transceiver.send_client_request(client_request).await { match self.gateway_transceiver.send_client_request(client_request).await {
Ok(_) => (), Ok(_) => (),
Err(e) => error!("Failed to send client request: {}", e), Err(e) => error!("Failed to send client request: {e}"),
}; };
}, },
None => { None => {
@@ -65,7 +65,7 @@ impl AcknowledgementListener {
return; return;
} }
trace!("Received {} from the mix network", frag_id); trace!("Received {frag_id} from the mix network");
self.stats_tx self.stats_tx
.report(PacketStatisticsEvent::RealAckReceived(ack_content.len()).into()); .report(PacketStatisticsEvent::RealAckReceived(ack_content.len()).into());
if let Err(err) = self if let Err(err) = self
@@ -126,7 +126,7 @@ impl ActionController {
fn handle_insert(&mut self, pending_acks: Vec<PendingAcknowledgement>) { fn handle_insert(&mut self, pending_acks: Vec<PendingAcknowledgement>) {
for pending_ack in pending_acks { for pending_ack in pending_acks {
let frag_id = pending_ack.message_chunk.fragment_identifier(); let frag_id = pending_ack.message_chunk.fragment_identifier();
trace!("{} is inserted", frag_id); trace!("{frag_id} is inserted");
if self if self
.pending_acks_data .pending_acks_data
@@ -161,22 +161,16 @@ impl ActionController {
let new_queue_key = self.pending_acks_timers.insert(frag_id, timeout); let new_queue_key = self.pending_acks_timers.insert(frag_id, timeout);
*queue_key = Some(new_queue_key) *queue_key = Some(new_queue_key)
} else { } else {
debug!( debug!("Tried to START TIMER on pending ack that is already gone! - {frag_id}");
"Tried to START TIMER on pending ack that is already gone! - {}",
frag_id
);
} }
} }
fn handle_remove(&mut self, frag_id: FragmentIdentifier) { fn handle_remove(&mut self, frag_id: FragmentIdentifier) {
trace!("{} is getting removed", frag_id); trace!("{frag_id} is getting removed");
match self.pending_acks_data.remove(&frag_id) { match self.pending_acks_data.remove(&frag_id) {
None => { None => {
debug!( debug!("Tried to REMOVE pending ack that is already gone! - {frag_id}");
"Tried to REMOVE pending ack that is already gone! - {}",
frag_id
);
} }
Some((_, queue_key)) => { Some((_, queue_key)) => {
if let Some(queue_key) = queue_key { if let Some(queue_key) = queue_key {
@@ -188,10 +182,7 @@ impl ActionController {
} else { } else {
// I'm not 100% sure if having a `None` key is even possible here // I'm not 100% sure if having a `None` key is even possible here
// (REMOVE would have to be called before START TIMER), // (REMOVE would have to be called before START TIMER),
debug!( debug!("Tried to REMOVE pending ack without TIMER active - {frag_id}");
"Tried to REMOVE pending ack without TIMER active - {}",
frag_id
);
} }
} }
} }
@@ -200,7 +191,7 @@ impl ActionController {
// initiated basically as a first step of retransmission. At first data has its delay updated // initiated basically as a first step of retransmission. At first data has its delay updated
// (as new sphinx packet was created with new expected delivery time) // (as new sphinx packet was created with new expected delivery time)
fn handle_update_pending_ack(&mut self, frag_id: FragmentIdentifier, delay: SphinxDelay) { fn handle_update_pending_ack(&mut self, frag_id: FragmentIdentifier, delay: SphinxDelay) {
trace!("{} is updating its delay", frag_id); trace!("{frag_id} is updating its delay");
// TODO: is it possible to solve this without either locking or temporarily removing the value? // TODO: is it possible to solve this without either locking or temporarily removing the value?
if let Some((pending_ack_data, queue_key)) = self.pending_acks_data.remove(&frag_id) { if let Some((pending_ack_data, queue_key)) = self.pending_acks_data.remove(&frag_id) {
// this Action is triggered by `RetransmissionRequestListener` (for 'normal' packets) // this Action is triggered by `RetransmissionRequestListener` (for 'normal' packets)
@@ -213,10 +204,7 @@ impl ActionController {
self.pending_acks_data self.pending_acks_data
.insert(frag_id, (Arc::new(inner_data), queue_key)); .insert(frag_id, (Arc::new(inner_data), queue_key));
} else { } else {
debug!( debug!("Tried to UPDATE TIMER on pending ack that is already gone! - {frag_id}");
"Tried to UPDATE TIMER on pending ack that is already gone! - {}",
frag_id
);
} }
} }
@@ -105,6 +105,9 @@ pub(crate) struct Config {
/// will be routed as usual, to the entry gateway, through three mix nodes, egressing /// will be routed as usual, to the entry gateway, through three mix nodes, egressing
/// through the exit gateway. If mix hops are disabled, traffic will be routed directly /// through the exit gateway. If mix hops are disabled, traffic will be routed directly
/// from the entry gateway to the exit gateway, bypassing the mix nodes. /// from the entry gateway to the exit gateway, bypassing the mix nodes.
///
/// This overrides the `use_legacy_sphinx_format` setting as reduced mix hops
/// requires use of the updated SURB packet format.
disable_mix_hops: bool, disable_mix_hops: bool,
/// Average delay a data packet is going to get delay at a single mixnode. /// Average delay a data packet is going to get delay at a single mixnode.
@@ -159,8 +162,12 @@ impl Config {
} }
/// Configure whether messages senders using this config should use mix hops or not when sending messages. /// Configure whether messages senders using this config should use mix hops or not when sending messages.
///
/// This overrides the `use_legacy_sphinx_format` setting as disabled mix hops
/// requires use of the updated SURB packet format.
pub fn disable_mix_hops(mut self, disable_mix_hops: bool) -> Self { pub fn disable_mix_hops(mut self, disable_mix_hops: bool) -> Self {
self.disable_mix_hops = disable_mix_hops; self.disable_mix_hops = disable_mix_hops;
self.use_legacy_sphinx_format = false;
self self
} }
} }
@@ -202,7 +202,7 @@ where
// well technically the message was not sent just yet, but now it's up to internal // well technically the message was not sent just yet, but now it's up to internal
// queues and client load rather than the required delay. So realistically we can treat // queues and client load rather than the required delay. So realistically we can treat
// whatever is about to happen as negligible additional delay. // whatever is about to happen as negligible additional delay.
trace!("{} is about to get sent to the mixnet", frag_id); trace!("{frag_id} is about to get sent to the mixnet");
if let Err(err) = self.sent_notifier.unbounded_send(frag_id) { if let Err(err) = self.sent_notifier.unbounded_send(frag_id) {
error!("Failed to notify about sent message: {err}"); error!("Failed to notify about sent message: {err}");
} }
@@ -164,11 +164,11 @@ impl SendingDelayController {
self.current_multiplier() self.current_multiplier()
); );
if self.current_multiplier() > 0 { if self.current_multiplier() > 0 {
log::debug!("{}", status_str); log::debug!("{status_str}");
} else if self.current_multiplier() > 1 { } else if self.current_multiplier() > 1 {
log::info!("{}", status_str); log::info!("{status_str}");
} else if self.current_multiplier() > 2 { } else if self.current_multiplier() > 2 {
log::warn!("{}", status_str); log::warn!("{status_str}");
} }
self.time_when_logged_about_elevated_multiplier = now; self.time_when_logged_about_elevated_multiplier = now;
} }
@@ -221,10 +221,7 @@ impl<R: MessageReceiver> ReceivedMessagesBuffer<R> {
let stored_messages = std::mem::take(&mut guard.messages); let stored_messages = std::mem::take(&mut guard.messages);
if !stored_messages.is_empty() { if !stored_messages.is_empty() {
if let Err(err) = sender.unbounded_send(stored_messages) { if let Err(err) = sender.unbounded_send(stored_messages) {
error!( error!("The sender channel we just received is already invalidated - {err:?}");
"The sender channel we just received is already invalidated - {:?}",
err
);
// put the values back to the buffer // put the values back to the buffer
// the returned error has two fields: err: SendError and val: T, // the returned error has two fields: err: SendError and val: T,
// where val is the value that was failed to get sent; // where val is the value that was failed to get sent;
@@ -217,14 +217,14 @@ where
.surbs_storage_ref() .surbs_storage_ref()
.contains_surbs_for(&recipient_tag) .contains_surbs_for(&recipient_tag)
{ {
warn!("received reply request for {:?} but we don't have any surbs stored for that recipient!", recipient_tag); warn!("received reply request for {recipient_tag:?} but we don't have any surbs stored for that recipient!");
return; return;
} }
trace!("handling reply to {:?}", recipient_tag); trace!("handling reply to {recipient_tag:?}");
let mut fragments = self.message_handler.split_reply_message(data); let mut fragments = self.message_handler.split_reply_message(data);
let total_size = fragments.len(); let total_size = fragments.len();
trace!("This reply requires {:?} SURBs", total_size); trace!("This reply requires {total_size:?} SURBs");
let available_surbs = self let available_surbs = self
.full_reply_storage .full_reply_storage
@@ -327,10 +327,7 @@ where
.await .await
{ {
let err = err.return_unused_surbs(self.full_reply_storage.surbs_storage_ref(), &target); let err = err.return_unused_surbs(self.full_reply_storage.surbs_storage_ref(), &target);
warn!( warn!("failed to request additional surbs from {target:?} - {err}");
"failed to request additional surbs from {:?} - {err}",
target
);
return Err(err); return Err(err);
} else { } else {
self.full_reply_storage self.full_reply_storage
@@ -409,10 +406,7 @@ where
err.return_unused_surbs(self.full_reply_storage.surbs_storage_ref(), &target); err.return_unused_surbs(self.full_reply_storage.surbs_storage_ref(), &target);
self.re_insert_pending_retransmission(&target, to_take); self.re_insert_pending_retransmission(&target, to_take);
warn!( warn!("failed to clear pending retransmission queue for {target:?} - {err}");
"failed to clear pending retransmission queue for {:?} - {err}",
target
);
return; return;
} }
}; };
@@ -489,7 +483,7 @@ where
let err = let err =
err.return_unused_surbs(self.full_reply_storage.surbs_storage_ref(), &target); err.return_unused_surbs(self.full_reply_storage.surbs_storage_ref(), &target);
self.re_insert_pending_replies(&target, to_send); self.re_insert_pending_replies(&target, to_send);
warn!("failed to clear pending queue for {:?} - {err}", target); warn!("failed to clear pending queue for {target:?} - {err}");
} }
} else { } else {
trace!("the pending queue is empty"); trace!("the pending queue is empty");
@@ -816,7 +810,7 @@ where
if diff > max_drop_wait { if diff > max_drop_wait {
to_remove.push(*pending_reply_target) to_remove.push(*pending_reply_target)
} else { } else {
debug!("We haven't received any surbs in {:?} from {pending_reply_target}. Going to explicitly ask for more", diff); debug!("We haven't received any surbs in {diff:?} from {pending_reply_target}. Going to explicitly ask for more");
to_request.push(*pending_reply_target); to_request.push(*pending_reply_target);
} }
} }
@@ -93,7 +93,7 @@ impl StatisticsControl {
None, None,
); );
if let Err(err) = self.report_tx.send(report_message).await { if let Err(err) = self.report_tx.send(report_message).await {
log::error!("Failed to report client stats: {:?}", err); log::error!("Failed to report client stats: {err:?}");
} else { } else {
self.stats.reset(); self.stats.reset();
} }
@@ -211,7 +211,7 @@ impl<T> TransmissionBuffer<T> {
}; };
let msg = self.pop_front_from_lane(&lane)?; let msg = self.pop_front_from_lane(&lane)?;
log::trace!("picking to send from lane: {:?}", lane); log::trace!("picking to send from lane: {lane:?}");
Some((lane, msg)) Some((lane, msg))
} }
+3 -3
View File
@@ -110,7 +110,7 @@ pub async fn gateways_for_init<R: Rng>(
let gateways = client.get_all_basic_entry_assigned_nodes_v2().await?.nodes; let gateways = client.get_all_basic_entry_assigned_nodes_v2().await?.nodes;
info!("nym api reports {} gateways", gateways.len()); info!("nym api reports {} gateways", gateways.len());
log::trace!("Gateways: {:#?}", gateways); log::trace!("Gateways: {gateways:#?}");
// filter out gateways below minimum performance and ones that could operate as a mixnode // filter out gateways below minimum performance and ones that could operate as a mixnode
// (we don't want instability) // (we don't want instability)
@@ -121,7 +121,7 @@ pub async fn gateways_for_init<R: Rng>(
.filter_map(|gateway| gateway.try_into().ok()) .filter_map(|gateway| gateway.try_into().ok())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
log::debug!("After checking validity: {}", valid_gateways.len()); log::debug!("After checking validity: {}", valid_gateways.len());
log::trace!("Valid gateways: {:#?}", valid_gateways); log::trace!("Valid gateways: {valid_gateways:#?}");
log::info!( log::info!(
"and {} after validity and performance filtering", "and {} after validity and performance filtering",
@@ -286,7 +286,7 @@ pub(super) fn get_specified_gateway(
gateways: &[RoutingNode], gateways: &[RoutingNode],
must_use_tls: bool, must_use_tls: bool,
) -> Result<RoutingNode, ClientCoreError> { ) -> Result<RoutingNode, ClientCoreError> {
log::debug!("Requesting specified gateway: {}", gateway_identity); log::debug!("Requesting specified gateway: {gateway_identity}");
let user_gateway = ed25519::PublicKey::from_base58_string(gateway_identity) let user_gateway = ed25519::PublicKey::from_base58_string(gateway_identity)
.map_err(ClientCoreError::UnableToCreatePublicKeyFromGatewayId)?; .map_err(ClientCoreError::UnableToCreatePublicKeyFromGatewayId)?;
@@ -7,18 +7,17 @@ use crate::nyxd::error::NyxdError;
use crate::nyxd::CosmWasmClient; use crate::nyxd::CosmWasmClient;
use async_trait::async_trait; use async_trait::async_trait;
use cosmrs::AccountId; use cosmrs::AccountId;
pub use nym_performance_contract_common::{
msg::QueryMsg as PerformanceQueryMsg, types::NetworkMonitorResponse,
};
use nym_performance_contract_common::{
EpochId, EpochMeasurementsPagedResponse, EpochNodePerformance, EpochPerformancePagedResponse,
FullHistoricalPerformancePagedResponse, HistoricalPerformance, NetworkMonitorInformation,
NetworkMonitorsPagedResponse, NodeId, NodeMeasurement, NodeMeasurementsResponse,
NodePerformance, NodePerformancePagedResponse, NodePerformanceResponse, RetiredNetworkMonitor,
RetiredNetworkMonitorsPagedResponse,
};
use serde::Deserialize; use serde::Deserialize;
pub use nym_performance_contract_common::{
msg::QueryMsg as PerformanceQueryMsg, types::NetworkMonitorResponse, EpochId,
EpochMeasurementsPagedResponse, EpochNodePerformance, EpochPerformancePagedResponse,
FullHistoricalPerformancePagedResponse, HistoricalPerformance, LastSubmission,
NetworkMonitorInformation, NetworkMonitorsPagedResponse, NodeId, NodeMeasurement,
NodeMeasurementsResponse, NodePerformance, NodePerformancePagedResponse,
NodePerformanceResponse, RetiredNetworkMonitor, RetiredNetworkMonitorsPagedResponse,
};
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
#[cfg_attr(not(target_arch = "wasm32"), async_trait)] #[cfg_attr(not(target_arch = "wasm32"), async_trait)]
pub trait PerformanceQueryClient { pub trait PerformanceQueryClient {
@@ -139,6 +138,11 @@ pub trait PerformanceQueryClient {
}) })
.await .await
} }
async fn get_last_submission(&self) -> Result<LastSubmission, NyxdError> {
self.query_performance_contract(PerformanceQueryMsg::LastSubmittedMeasurement {})
.await
}
} }
// extension trait to the query client to deal with the paged queries // extension trait to the query client to deal with the paged queries
@@ -212,6 +216,7 @@ where
mod tests { mod tests {
use super::*; use super::*;
use crate::nyxd::contract_traits::tests::IgnoreValue; use crate::nyxd::contract_traits::tests::IgnoreValue;
use nym_performance_contract_common::QueryMsg;
// it's enough that this compiles and clippy is happy about it // it's enough that this compiles and clippy is happy about it
#[allow(dead_code)] #[allow(dead_code)]
@@ -260,6 +265,7 @@ mod tests {
PerformanceQueryMsg::RetiredNetworkMonitorsPaged { start_after, limit } => client PerformanceQueryMsg::RetiredNetworkMonitorsPaged { start_after, limit } => client
.get_retired_network_monitors_paged(start_after, limit) .get_retired_network_monitors_paged(start_after, limit)
.ignore(), .ignore(),
QueryMsg::LastSubmittedMeasurement {} => client.get_last_submission().ignore(),
}; };
} }
} }
+2 -2
View File
@@ -49,14 +49,14 @@ pub fn show_error<E>(e: E)
where where
E: Display, E: Display,
{ {
error!("{}", e); error!("{e}");
} }
pub fn show_error_passthrough<E>(e: E) -> E pub fn show_error_passthrough<E>(e: E) -> E
where where
E: Error + Display, E: Error + Display,
{ {
error!("{}", e); error!("{e}");
e e
} }
@@ -42,7 +42,7 @@ pub async fn query_balance(
.address .address
.unwrap_or_else(|| address_from_mnemonic.expect("please provide a mnemonic")); .unwrap_or_else(|| address_from_mnemonic.expect("please provide a mnemonic"));
info!("Getting balance for {}...", address); info!("Getting balance for {address}...");
match client.get_all_balances(&address).await { match client.get_all_balances(&address).await {
Ok(coins) => { Ok(coins) => {
@@ -57,17 +57,17 @@ pub fn get_pubkey_from_mnemonic(address: AccountId, prefix: &str, mnemonic: bip3
println!("{}", account.public_key().to_string()); println!("{}", account.public_key().to_string());
} }
None => { None => {
error!("Could not derive key that matches {}", address) error!("Could not derive key that matches {address}")
} }
}, },
Err(e) => { Err(e) => {
error!("Failed to derive accounts. {}", e); error!("Failed to derive accounts. {e}");
} }
} }
} }
pub async fn get_pubkey_from_chain(address: AccountId, client: &QueryClient) { pub async fn get_pubkey_from_chain(address: AccountId, client: &QueryClient) {
info!("Getting public key for address {} from chain...", address); info!("Getting public key for address {address} from chain...");
match client.get_account(&address).await { match client.get_account(&address).await {
Ok(Some(account)) => { Ok(Some(account)) => {
if let Ok(base_account) = account.try_get_base_account() { if let Ok(base_account) = account.try_get_base_account() {
@@ -37,7 +37,7 @@ pub async fn send_multiple(args: Args, client: &SigningClient) {
let rows = InputFileReader::new(&args.input); let rows = InputFileReader::new(&args.input);
if let Err(e) = rows { if let Err(e) = rows {
error!("Failed to read input file: {}", e); error!("Failed to read input file: {e}");
return; return;
} }
let rows = rows.unwrap(); let rows = rows.unwrap();
@@ -67,7 +67,7 @@ pub async fn send_multiple(args: Args, client: &SigningClient) {
.prompt(); .prompt();
if let Err(e) = ans { if let Err(e) = ans {
info!("Aborting, {}...", e); info!("Aborting, {e}...");
return; return;
} }
if let Ok(false) = ans { if let Ok(false) = ans {
@@ -100,13 +100,10 @@ pub async fn send_multiple(args: Args, client: &SigningClient) {
println!("Transaction hash: {}", &res.hash); println!("Transaction hash: {}", &res.hash);
if let Some(output_filename) = args.output { if let Some(output_filename) = args.output {
println!("\nWriting output log to {}", output_filename); println!("\nWriting output log to {output_filename}");
if let Err(e) = write_output_file(rows, res, &output_filename) { if let Err(e) = write_output_file(rows, res, &output_filename) {
error!( error!("Failed to write output file {output_filename} with error {e}");
"Failed to write output file {} with error {}",
output_filename, e
);
} }
} }
} }
@@ -136,7 +133,7 @@ fn write_output_file(
.collect::<Vec<String>>() .collect::<Vec<String>>()
.join("\n"); .join("\n");
Ok(file.write_all(format!("{}\n", data).as_bytes())?) Ok(file.write_all(format!("{data}\n").as_bytes())?)
} }
#[derive(Debug)] #[derive(Debug)]
@@ -171,7 +168,7 @@ impl InputFileReader {
// multiply when a whole token amount, e.g. 50nym (50.123456nym is not allowed, that must be input as 50123456unym) // multiply when a whole token amount, e.g. 50nym (50.123456nym is not allowed, that must be input as 50123456unym)
let (amount, denom) = if !denom.starts_with('u') { let (amount, denom) = if !denom.starts_with('u') {
(amount * 1_000_000u128, format!("u{}", denom)) (amount * 1_000_000u128, format!("u{denom}"))
} else { } else {
(amount, denom) (amount, denom)
}; };
@@ -55,6 +55,6 @@ pub async fn execute(args: Args, client: SigningClient) {
.await .await
{ {
Ok(res) => info!("SUCCESS ✅\n{}", json!(res)), Ok(res) => info!("SUCCESS ✅\n{}", json!(res)),
Err(e) => error!("FAILURE ❌\n{}", e), Err(e) => error!("FAILURE ❌\n{e}"),
} }
} }
@@ -43,7 +43,7 @@ pub struct Args {
pub async fn generate(args: Args) { pub async fn generate(args: Args) {
info!("Starting to generate vesting contract instantiate msg"); info!("Starting to generate vesting contract instantiate msg");
debug!("Received arguments: {:?}", args); debug!("Received arguments: {args:?}");
let multisig_addr = args.multisig_addr.unwrap_or_else(|| { let multisig_addr = args.multisig_addr.unwrap_or_else(|| {
let address = std::env::var(nym_network_defaults::var_names::REWARDING_VALIDATOR_ADDRESS) let address = std::env::var(nym_network_defaults::var_names::REWARDING_VALIDATOR_ADDRESS)
@@ -97,7 +97,7 @@ pub async fn generate(args: Args) {
key_size: DEFAULT_DEALINGS as u32, key_size: DEFAULT_DEALINGS as u32,
}; };
debug!("instantiate_msg: {:?}", instantiate_msg); debug!("instantiate_msg: {instantiate_msg:?}");
let res = let res =
serde_json::to_string(&instantiate_msg).expect("failed to convert instantiate msg to json"); serde_json::to_string(&instantiate_msg).expect("failed to convert instantiate msg to json");
@@ -28,7 +28,7 @@ pub struct Args {
pub async fn generate(args: Args) { pub async fn generate(args: Args) {
info!("Starting to generate vesting contract instantiate msg"); info!("Starting to generate vesting contract instantiate msg");
debug!("Received arguments: {:?}", args); debug!("Received arguments: {args:?}");
let group_addr = args.group_addr.unwrap_or_else(|| { let group_addr = args.group_addr.unwrap_or_else(|| {
let address = std::env::var(nym_network_defaults::var_names::GROUP_CONTRACT_ADDRESS) let address = std::env::var(nym_network_defaults::var_names::GROUP_CONTRACT_ADDRESS)
@@ -51,7 +51,7 @@ pub async fn generate(args: Args) {
deposit_amount: args.deposit_amount, deposit_amount: args.deposit_amount,
}; };
debug!("instantiate_msg: {:?}", instantiate_msg); debug!("instantiate_msg: {instantiate_msg:?}");
let res = let res =
serde_json::to_string(&instantiate_msg).expect("failed to convert instantiate msg to json"); serde_json::to_string(&instantiate_msg).expect("failed to convert instantiate msg to json");
@@ -88,7 +88,7 @@ pub struct Args {
pub async fn generate(args: Args) { pub async fn generate(args: Args) {
info!("Starting to generate mixnet contract instantiate msg"); info!("Starting to generate mixnet contract instantiate msg");
debug!("Received arguments: {:?}", args); debug!("Received arguments: {args:?}");
let initial_rewarding_params = InitialRewardingParams { let initial_rewarding_params = InitialRewardingParams {
initial_reward_pool: Decimal::from_atomics(args.initial_reward_pool, 0) initial_reward_pool: Decimal::from_atomics(args.initial_reward_pool, 0)
@@ -114,7 +114,7 @@ pub async fn generate(args: Args) {
}, },
}; };
debug!("initial_rewarding_params: {:?}", initial_rewarding_params); debug!("initial_rewarding_params: {initial_rewarding_params:?}");
let rewarding_validator_address = args.rewarding_validator_address.unwrap_or_else(|| { let rewarding_validator_address = args.rewarding_validator_address.unwrap_or_else(|| {
let address = std::env::var(nym_network_defaults::var_names::REWARDING_VALIDATOR_ADDRESS) let address = std::env::var(nym_network_defaults::var_names::REWARDING_VALIDATOR_ADDRESS)
@@ -160,7 +160,7 @@ pub async fn generate(args: Args) {
key_validity_in_epochs: None, key_validity_in_epochs: None,
}; };
debug!("instantiate_msg: {:?}", instantiate_msg); debug!("instantiate_msg: {instantiate_msg:?}");
let res = let res =
serde_json::to_string(&instantiate_msg).expect("failed to convert instantiate msg to json"); serde_json::to_string(&instantiate_msg).expect("failed to convert instantiate msg to json");
@@ -31,7 +31,7 @@ pub struct Args {
pub async fn generate(args: Args) { pub async fn generate(args: Args) {
info!("Starting to generate vesting contract instantiate msg"); info!("Starting to generate vesting contract instantiate msg");
debug!("Received arguments: {:?}", args); debug!("Received arguments: {args:?}");
let ecash_contract_address = args.ecash_contract_address.unwrap_or_else(|| { let ecash_contract_address = args.ecash_contract_address.unwrap_or_else(|| {
let address = std::env::var(nym_network_defaults::var_names::ECASH_CONTRACT_ADDRESS) let address = std::env::var(nym_network_defaults::var_names::ECASH_CONTRACT_ADDRESS)
@@ -60,7 +60,7 @@ pub async fn generate(args: Args) {
coconut_dkg_contract_address: coconut_dkg_contract_address.to_string(), coconut_dkg_contract_address: coconut_dkg_contract_address.to_string(),
}; };
debug!("instantiate_msg: {:?}", instantiate_msg); debug!("instantiate_msg: {instantiate_msg:?}");
let res = let res =
serde_json::to_string(&instantiate_msg).expect("failed to convert instantiate msg to json"); serde_json::to_string(&instantiate_msg).expect("failed to convert instantiate msg to json");
@@ -21,7 +21,7 @@ pub struct Args {
pub async fn generate(args: Args) { pub async fn generate(args: Args) {
info!("Starting to generate vesting contract instantiate msg"); info!("Starting to generate vesting contract instantiate msg");
debug!("Received arguments: {:?}", args); debug!("Received arguments: {args:?}");
let mixnet_contract_address = args.mixnet_contract_address.unwrap_or_else(|| { let mixnet_contract_address = args.mixnet_contract_address.unwrap_or_else(|| {
let address = std::env::var(nym_network_defaults::var_names::MIXNET_CONTRACT_ADDRESS) let address = std::env::var(nym_network_defaults::var_names::MIXNET_CONTRACT_ADDRESS)
@@ -39,7 +39,7 @@ pub async fn generate(args: Args) {
mix_denom, mix_denom,
}; };
debug!("instantiate_msg: {:?}", instantiate_msg); debug!("instantiate_msg: {instantiate_msg:?}");
let res = let res =
serde_json::to_string(&instantiate_msg).expect("failed to convert instantiate msg to json"); serde_json::to_string(&instantiate_msg).expect("failed to convert instantiate msg to json");
@@ -72,7 +72,7 @@ pub async fn init(args: Args, client: SigningClient, network_details: &NymNetwor
.await .await
.expect("failed to instantiate the contract!"); .expect("failed to instantiate the contract!");
info!("Init result: {:?}", res); info!("Init result: {res:?}");
println!("{}", res.contract_address) println!("{}", res.contract_address)
} }
@@ -47,5 +47,5 @@ pub async fn migrate(args: Args, client: SigningClient) {
.expect("failed to migrate the contract!") .expect("failed to migrate the contract!")
}; };
info!("Migrate result: {:?}", res); info!("Migrate result: {res:?}");
} }
@@ -31,7 +31,7 @@ pub async fn upload(args: Args, client: SigningClient) {
.await .await
.expect("failed to upload the contract!"); .expect("failed to upload the contract!");
info!("Upload result: {:?}", res); info!("Upload result: {res:?}");
println!("{}", res.code_id) println!("{}", res.code_id)
} }
@@ -47,5 +47,5 @@ pub async fn delegate_to_mixnode(args: Args, client: SigningClient) {
.await .await
.expect("failed to delegate to mixnode!"); .expect("failed to delegate to mixnode!");
info!("delegating to mixnode: {:?}", res); info!("delegating to mixnode: {res:?}");
} }
@@ -196,7 +196,7 @@ pub async fn delegate_to_multiple_mixnodes(args: Args, client: SigningClient) {
let records = match InputFileReader::new(&args.input) { let records = match InputFileReader::new(&args.input) {
Ok(records) => records, Ok(records) => records,
Err(e) => { Err(e) => {
println!("Error reading input file: {}", e); println!("Error reading input file: {e}");
return; return;
} }
}; };
@@ -262,11 +262,11 @@ pub async fn delegate_to_multiple_mixnodes(args: Args, client: SigningClient) {
} }
if !undelegation_msgs.is_empty() { if !undelegation_msgs.is_empty() {
println!("Undelegation records : \n{}\n\n", undelegation_table); println!("Undelegation records : \n{undelegation_table}\n\n");
} }
if !delegation_msgs.is_empty() { if !delegation_msgs.is_empty() {
println!("Delegation records : \n{}\n\n", delegation_table); println!("Delegation records : \n{delegation_table}\n\n");
} }
let ans = inquire::Confirm::new("Do you want to continue with the shown operations?") let ans = inquire::Confirm::new("Do you want to continue with the shown operations?")
@@ -275,7 +275,7 @@ pub async fn delegate_to_multiple_mixnodes(args: Args, client: SigningClient) {
.prompt(); .prompt();
if let Err(e) = ans { if let Err(e) = ans {
info!("Aborting, {}...", e); info!("Aborting, {e}...");
return; return;
} }
@@ -348,7 +348,7 @@ pub async fn delegate_to_multiple_mixnodes(args: Args, client: SigningClient) {
if args.output.is_some() { if args.output.is_some() {
if let Err(e) = write_to_csv(output_details, args.output) { if let Err(e) = write_to_csv(output_details, args.output) {
info!("Failed to write to CSV, {}", e); info!("Failed to write to CSV, {e}");
} }
} }
} }
@@ -38,5 +38,5 @@ pub async fn migrate_vested_delegation(args: Args, client: SigningClient) {
.await .await
.expect("failed to migrate delegation!"); .expect("failed to migrate delegation!");
info!("migration result: {:?}", res) info!("migration result: {res:?}")
} }
@@ -40,5 +40,5 @@ pub async fn claim_delegator_reward(args: Args, client: SigningClient) {
.await .await
.expect("failed to claim delegator-reward"); .expect("failed to claim delegator-reward");
info!("Claiming delegator reward: {:?}", res) info!("Claiming delegator reward: {res:?}")
} }
@@ -40,5 +40,5 @@ pub async fn vesting_claim_delegator_reward(args: Args, client: SigningClient) {
.await .await
.expect("failed to claim vesting delegator-reward"); .expect("failed to claim vesting delegator-reward");
info!("Claiming vesting delegator reward: {:?}", res) info!("Claiming vesting delegator reward: {res:?}")
} }
@@ -40,5 +40,5 @@ pub async fn undelegate_from_mixnode(args: Args, client: SigningClient) {
.await .await
.expect("failed to remove stake from mixnode!"); .expect("failed to remove stake from mixnode!");
info!("removing stake from mixnode: {:?}", res) info!("removing stake from mixnode: {res:?}")
} }
@@ -53,5 +53,5 @@ pub async fn vesting_delegate_to_mixnode(args: Args, client: SigningClient) {
.await .await
.expect("failed to delegate to mixnode!"); .expect("failed to delegate to mixnode!");
info!("vesting delegating to mixnode: {:?}", res); info!("vesting delegating to mixnode: {res:?}");
} }
@@ -45,5 +45,5 @@ pub async fn vesting_undelegate_from_mixnode(args: Args, client: SigningClient)
.await .await
.expect("failed to remove stake from vesting account on mixnode!"); .expect("failed to remove stake from vesting account on mixnode!");
info!("removing stake from vesting mixnode: {:?}", res) info!("removing stake from vesting mixnode: {res:?}")
} }
@@ -73,5 +73,5 @@ pub async fn bond_gateway(args: Args, client: SigningClient) {
.await .await
.expect("failed to bond gateway!"); .expect("failed to bond gateway!");
info!("Bonding result: {:?}", res) info!("Bonding result: {res:?}")
} }
@@ -52,5 +52,5 @@ pub async fn migrate_to_nymnode(args: Args, client: SigningClient) {
.await .await
.expect("failed to migrate gateway!"); .expect("failed to migrate gateway!");
info!("migration result: {:?}", res) info!("migration result: {res:?}")
} }
@@ -56,5 +56,5 @@ pub async fn update_config(args: Args, client: SigningClient) {
.await .await
.expect("updating gateway config"); .expect("updating gateway config");
info!("gateway config updated: {:?}", res) info!("gateway config updated: {res:?}")
} }
@@ -57,5 +57,5 @@ pub async fn vesting_update_config(args: Args, client: SigningClient) {
.await .await
.expect("updating vesting gateway config"); .expect("updating vesting gateway config");
info!("gateway config updated: {:?}", res) info!("gateway config updated: {res:?}")
} }
@@ -17,5 +17,5 @@ pub async fn unbond_gateway(client: SigningClient) {
.await .await
.expect("failed to unbond gateway!"); .expect("failed to unbond gateway!");
info!("Unbonding result: {:?}", res) info!("Unbonding result: {res:?}")
} }
@@ -73,5 +73,5 @@ pub async fn vesting_bond_gateway(args: Args, client: SigningClient) {
.await .await
.expect("failed to bond gateway!"); .expect("failed to bond gateway!");
info!("Vesting bonding gateway result: {:?}", res) info!("Vesting bonding gateway result: {res:?}")
} }
@@ -17,5 +17,5 @@ pub async fn vesting_unbond_gateway(client: SigningClient) {
.await .await
.expect("failed to unbond vesting gateway!"); .expect("failed to unbond vesting gateway!");
info!("Unbonding vesting result: {:?}", res) info!("Unbonding vesting result: {res:?}")
} }
@@ -106,5 +106,5 @@ pub async fn bond_mixnode(args: Args, client: SigningClient) {
.await .await
.expect("failed to bond mixnode!"); .expect("failed to bond mixnode!");
info!("Bonding result: {:?}", res) info!("Bonding result: {res:?}")
} }
@@ -25,5 +25,5 @@ pub async fn decrease_pledge(args: Args, client: SigningClient) {
.await .await
.expect("failed to decrease pledge!"); .expect("failed to decrease pledge!");
info!("decreasing pledge: {:?}", res); info!("decreasing pledge: {res:?}");
} }
@@ -15,5 +15,5 @@ pub async fn migrate_vested_mixnode(_args: Args, client: SigningClient) {
.await .await
.expect("failed to migrate mixnode!"); .expect("failed to migrate mixnode!");
info!("migration result: {:?}", res) info!("migration result: {res:?}")
} }
@@ -15,5 +15,5 @@ pub async fn migrate_to_nymnode(_args: Args, client: SigningClient) {
.await .await
.expect("failed to migrate mixnode!"); .expect("failed to migrate mixnode!");
info!("migration result: {:?}", res) info!("migration result: {res:?}")
} }
@@ -25,5 +25,5 @@ pub async fn pledge_more(args: Args, client: SigningClient) {
.await .await
.expect("failed to pledge more!"); .expect("failed to pledge more!");
info!("pledging more: {:?}", res); info!("pledging more: {res:?}");
} }
@@ -17,5 +17,5 @@ pub async fn claim_operator_reward(_args: Args, client: SigningClient) {
.await .await
.expect("failed to claim operator reward"); .expect("failed to claim operator reward");
info!("Claiming operator reward: {:?}", res) info!("Claiming operator reward: {res:?}")
} }
@@ -20,5 +20,5 @@ pub async fn vesting_claim_operator_reward(client: SigningClient) {
.await .await
.expect("failed to claim vesting operator reward"); .expect("failed to claim vesting operator reward");
info!("Claiming vesting operator reward: {:?}", res) info!("Claiming vesting operator reward: {res:?}")
} }
@@ -64,5 +64,5 @@ pub async fn update_config(args: Args, client: SigningClient) {
.await .await
.expect("updating mix-node config"); .expect("updating mix-node config");
info!("mixnode config updated: {:?}", res) info!("mixnode config updated: {res:?}")
} }
@@ -65,5 +65,5 @@ pub async fn vesting_update_config(client: SigningClient, args: Args) {
.await .await
.expect("updating vesting mix-node config"); .expect("updating vesting mix-node config");
info!("mixnode config updated: {:?}", res) info!("mixnode config updated: {res:?}")
} }
@@ -18,5 +18,5 @@ pub async fn unbond_mixnode(_args: Args, client: SigningClient) {
.await .await
.expect("failed to unbond mixnode!"); .expect("failed to unbond mixnode!");
info!("Unbonding result: {:?}", res) info!("Unbonding result: {res:?}")
} }
@@ -106,5 +106,5 @@ pub async fn vesting_bond_mixnode(client: SigningClient, args: Args, denom: &str
.await .await
.expect("failed to bond vesting mixnode!"); .expect("failed to bond vesting mixnode!");
info!("Bonding vesting result: {:?}", res) info!("Bonding vesting result: {res:?}")
} }
@@ -25,5 +25,5 @@ pub async fn vesting_decrease_pledge(args: Args, client: SigningClient) {
.await .await
.expect("failed to vesting decrease pledge!"); .expect("failed to vesting decrease pledge!");
info!("vesting decreasing pledge: {:?}", res); info!("vesting decreasing pledge: {res:?}");
} }
@@ -26,5 +26,5 @@ pub async fn vesting_pledge_more(args: Args, client: SigningClient) {
.await .await
.expect("failed to pledge more!"); .expect("failed to pledge more!");
info!("vesting pledge more: {:?}", res); info!("vesting pledge more: {res:?}");
} }
@@ -20,5 +20,5 @@ pub async fn vesting_unbond_mixnode(client: SigningClient) {
.await .await
.expect("failed to unbond vesting mixnode!"); .expect("failed to unbond vesting mixnode!");
info!("Unbonding vesting result: {:?}", res) info!("Unbonding vesting result: {res:?}")
} }
@@ -85,5 +85,5 @@ pub async fn bond_nymnode(args: Args, client: SigningClient) {
.await .await
.expect("failed to bond nymnode!"); .expect("failed to bond nymnode!");
info!("Bonding result: {:?}", res) info!("Bonding result: {res:?}")
} }
@@ -25,5 +25,5 @@ pub async fn decrease_pledge(args: Args, client: SigningClient) {
.await .await
.expect("failed to decrease pledge!"); .expect("failed to decrease pledge!");
info!("decreasing pledge: {:?}", res); info!("decreasing pledge: {res:?}");
} }
@@ -25,5 +25,5 @@ pub async fn increase_pledge(args: Args, client: SigningClient) {
.await .await
.expect("failed to pledge more!"); .expect("failed to pledge more!");
info!("pledging more: {:?}", res); info!("pledging more: {res:?}");
} }
@@ -17,5 +17,5 @@ pub async fn claim_operator_reward(_args: Args, client: SigningClient) {
.await .await
.expect("failed to claim operator reward"); .expect("failed to claim operator reward");
info!("Claiming operator reward: {:?}", res) info!("Claiming operator reward: {res:?}")
} }
@@ -46,5 +46,5 @@ pub async fn update_config(args: Args, client: SigningClient) {
.await .await
.expect("updating nym node config"); .expect("updating nym node config");
info!("nym node config updated: {:?}", res) info!("nym node config updated: {res:?}")
} }
@@ -68,6 +68,6 @@ pub async fn update_cost_params(args: Args, client: SigningClient) -> anyhow::Re
.await .await
.expect("failed to update cost params"); .expect("failed to update cost params");
info!("Cost params result: {:?}", res); info!("Cost params result: {res:?}");
Ok(()) Ok(())
} }
@@ -18,5 +18,5 @@ pub async fn unbond_nymnode(_args: Args, client: SigningClient) {
.await .await
.expect("failed to unbond Nym Node!"); .expect("failed to unbond Nym Node!");
info!("Unbonding result: {:?}", res) info!("Unbonding result: {res:?}")
} }
@@ -52,7 +52,7 @@ pub fn sign(args: Args, prefix: &str, mnemonic: Option<bip39::Mnemonic>) {
println!("{}", json!(output)); println!("{}", json!(output));
} }
Err(e) => { Err(e) => {
error!("Failed to sign message. {}", e); error!("Failed to sign message. {e}");
} }
} }
} }
@@ -61,7 +61,7 @@ pub fn sign(args: Args, prefix: &str, mnemonic: Option<bip39::Mnemonic>) {
} }
}, },
Err(e) => { Err(e) => {
error!("Failed to derive accounts. {}", e); error!("Failed to derive accounts. {e}");
} }
} }
} }
@@ -38,7 +38,7 @@ pub async fn verify(args: Args, client: &QueryClient) {
let public_key = match AccountId::from_str(&args.public_key_or_address) { let public_key = match AccountId::from_str(&args.public_key_or_address) {
Ok(address) => { Ok(address) => {
info!("Found account address instead of public key, so looking up public key for {} from chain", address); info!("Found account address instead of public key, so looking up public key for {address} from chain");
match client.get_account_public_key(&address).await.ok() { match client.get_account_public_key(&address).await.ok() {
Some(public_key) => { Some(public_key) => {
if let Some(k) = public_key { if let Some(k) = public_key {
@@ -48,8 +48,7 @@ pub async fn verify(args: Args, client: &QueryClient) {
} }
None => { None => {
error!( error!(
"Address {} does not have a public key recorded on the chain. This is probably because the account has never signed a transaction.", "Address {address} does not have a public key recorded on the chain. This is probably because the account has never signed a transaction."
address
); );
None None
} }
@@ -58,7 +57,7 @@ pub async fn verify(args: Args, client: &QueryClient) {
Err(_) => match PublicKey::from_json(&args.public_key_or_address) { Err(_) => match PublicKey::from_json(&args.public_key_or_address) {
Ok(parsed) => Some(parsed), Ok(parsed) => Some(parsed),
Err(e) => { Err(e) => {
error!("Public key should be JSON. Unable to parse: {}", e); error!("Public key should be JSON. Unable to parse: {e}");
None None
} }
}, },
@@ -78,7 +77,7 @@ pub async fn verify(args: Args, client: &QueryClient) {
) { ) {
Ok(()) => println!("SUCCESS ✅ signature verified"), Ok(()) => println!("SUCCESS ✅ signature verified"),
Err(e) => { Err(e) => {
error!("FAILURE ❌ Signature verification failed: {}", e); error!("FAILURE ❌ Signature verification failed: {e}");
} }
} }
} }
@@ -86,6 +86,6 @@ pub async fn create(args: Args, client: SigningClient, network_details: &NymNetw
.await .await
.unwrap(); .unwrap();
info!("Vesting result: {:?}", res); info!("Vesting result: {res:?}");
info!("Coin send result: {:?}", send_coin_response); info!("Coin send result: {send_coin_response:?}");
} }
@@ -29,7 +29,7 @@ pub async fn query(args: Args, client: QueryClient, address_from_mnemonic: Optio
.address .address
.unwrap_or_else(|| address_from_mnemonic.expect("please provide a mnemonic")); .unwrap_or_else(|| address_from_mnemonic.expect("please provide a mnemonic"));
info!("Checking account {} for a vesting schedule...", account_id); info!("Checking account {account_id} for a vesting schedule...");
let vesting_address = account_id.to_string(); let vesting_address = account_id.to_string();
let denom = client.current_chain_details().mix_denom.base.as_str(); let denom = client.current_chain_details().mix_denom.base.as_str();
@@ -44,6 +44,17 @@ pub struct RewardEstimate {
pub operating_cost: Decimal, pub operating_cost: Decimal,
} }
impl RewardEstimate {
pub const fn zero() -> RewardEstimate {
RewardEstimate {
total_node_reward: Decimal::zero(),
operator: Decimal::zero(),
delegates: Decimal::zero(),
operating_cost: Decimal::zero(),
}
}
}
#[cw_serde] #[cw_serde]
#[derive(Copy, Default)] #[derive(Copy, Default)]
pub struct RewardDistribution { pub struct RewardDistribution {
@@ -4,6 +4,7 @@
pub mod storage_keys { pub mod storage_keys {
pub const CONTRACT_ADMIN: &str = "contract-admin"; pub const CONTRACT_ADMIN: &str = "contract-admin";
pub const INITIAL_EPOCH_ID: &str = "initial-epoch-id"; pub const INITIAL_EPOCH_ID: &str = "initial-epoch-id";
pub const LAST_SUBMISSION: &str = "last-submission";
pub const MIXNET_CONTRACT: &str = "mixnet-contract"; pub const MIXNET_CONTRACT: &str = "mixnet-contract";
pub const AUTHORISED_COUNT: &str = "authorised-count"; pub const AUTHORISED_COUNT: &str = "authorised-count";
pub const AUTHORISED: &str = "authorised"; pub const AUTHORISED: &str = "authorised";
@@ -7,9 +7,9 @@ use cosmwasm_schema::cw_serde;
#[cfg(feature = "schema")] #[cfg(feature = "schema")]
use crate::types::{ use crate::types::{
EpochMeasurementsPagedResponse, EpochPerformancePagedResponse, EpochMeasurementsPagedResponse, EpochPerformancePagedResponse,
FullHistoricalPerformancePagedResponse, NetworkMonitorResponse, NetworkMonitorsPagedResponse, FullHistoricalPerformancePagedResponse, LastSubmission, NetworkMonitorResponse,
NodeMeasurementsResponse, NodePerformancePagedResponse, NodePerformanceResponse, NetworkMonitorsPagedResponse, NodeMeasurementsResponse, NodePerformancePagedResponse,
RetiredNetworkMonitorsPagedResponse, NodePerformanceResponse, RetiredNetworkMonitorsPagedResponse,
}; };
#[cw_serde] #[cw_serde]
@@ -113,6 +113,10 @@ pub enum QueryMsg {
start_after: Option<String>, start_after: Option<String>,
limit: Option<u32>, limit: Option<u32>,
}, },
/// Returns information regarding the latest submitted performance data
#[cfg_attr(feature = "schema", returns(LastSubmission))]
LastSubmittedMeasurement {},
} }
#[cw_serde] #[cw_serde]
@@ -2,12 +2,28 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
use cosmwasm_schema::cw_serde; use cosmwasm_schema::cw_serde;
use cosmwasm_std::{Addr, Env}; use cosmwasm_std::{Addr, Env, Timestamp};
use nym_contracts_common::Percent; use nym_contracts_common::Percent;
pub type EpochId = u32; pub type EpochId = u32;
pub type NodeId = u32; pub type NodeId = u32;
#[cw_serde]
pub struct LastSubmission {
pub block_height: u64,
pub block_time: Timestamp,
// not as relevant, but might as well store it
pub data: Option<LastSubmittedData>,
}
#[cw_serde]
pub struct LastSubmittedData {
pub sender: Addr,
pub epoch_id: EpochId,
pub data: NodePerformance,
}
#[cw_serde] #[cw_serde]
pub struct NetworkMonitorDetails { pub struct NetworkMonitorDetails {
pub address: Addr, pub address: Addr,
+1 -1
View File
@@ -95,7 +95,7 @@ where
} else if let Some(final_timestamp) = epoch.final_timestamp_secs() { } else if let Some(final_timestamp) = epoch.final_timestamp_secs() {
// Use 1 additional second to not start the next iteration immediately and spam get_current_epoch queries // Use 1 additional second to not start the next iteration immediately and spam get_current_epoch queries
let secs_until_final = final_timestamp.saturating_sub(current_timestamp_secs) + 1; let secs_until_final = final_timestamp.saturating_sub(current_timestamp_secs) + 1;
info!("Approximately {} seconds until coconut is available. Sleeping until then. You can safely kill the process at any moment.", secs_until_final); info!("Approximately {secs_until_final} seconds until coconut is available. Sleeping until then. You can safely kill the process at any moment.");
tokio::time::sleep(Duration::from_secs(secs_until_final)).await; tokio::time::sleep(Duration::from_secs(secs_until_final)).await;
} else if matches!(epoch.state, EpochState::WaitingInitialisation) { } else if matches!(epoch.state, EpochState::WaitingInitialisation) {
info!("dkg hasn't been initialised yet and it is not known when it will be. Going to check again later"); info!("dkg hasn't been initialised yet and it is not known when it will be. Going to check again later");
+2 -2
View File
@@ -7,9 +7,9 @@ use std::env;
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
let out_dir = env::var("OUT_DIR").unwrap(); let out_dir = env::var("OUT_DIR").unwrap();
let database_path = format!("{}/gateway-stats-example.sqlite", out_dir); let database_path = format!("{out_dir}/gateway-stats-example.sqlite");
let mut conn = SqliteConnection::connect(&format!("sqlite://{}?mode=rwc", database_path)) let mut conn = SqliteConnection::connect(&format!("sqlite://{database_path}?mode=rwc"))
.await .await
.expect("Failed to create SQLx database connection"); .expect("Failed to create SQLx database connection");
+2 -2
View File
@@ -7,9 +7,9 @@ use std::env;
#[tokio::main] #[tokio::main]
async fn main() { async fn main() {
let out_dir = env::var("OUT_DIR").unwrap(); let out_dir = env::var("OUT_DIR").unwrap();
let database_path = format!("{}/gateway-example.sqlite", out_dir); let database_path = format!("{out_dir}/gateway-example.sqlite");
let mut conn = SqliteConnection::connect(&format!("sqlite://{}?mode=rwc", database_path)) let mut conn = SqliteConnection::connect(&format!("sqlite://{database_path}?mode=rwc"))
.await .await
.expect("Failed to create SQLx database connection"); .expect("Failed to create SQLx database connection");
+1 -1
View File
@@ -37,7 +37,7 @@ impl std::fmt::Display for ClientType {
ClientType::EntryWireguard => "entry_wireguard", ClientType::EntryWireguard => "entry_wireguard",
ClientType::ExitWireguard => "exit_wireguard", ClientType::ExitWireguard => "exit_wireguard",
}; };
write!(f, "{}", s) write!(f, "{s}")
} }
} }
+1 -1
View File
@@ -141,7 +141,7 @@ mod tests {
}; };
assert_eq!( assert_eq!(
format!("{}", user_agent), format!("{user_agent}"),
"nym-mixnode/0.11.0/x86_64-unknown-linux-gnu/abcdefg" "nym-mixnode/0.11.0/x86_64-unknown-linux-gnu/abcdefg"
); );
} }
+1
View File
@@ -19,6 +19,7 @@ colored = { workspace = true, optional = true }
futures = { workspace = true, optional = true } futures = { workspace = true, optional = true }
mime = { workspace = true, optional = true } mime = { workspace = true, optional = true }
serde = { workspace = true, features = ["derive"] } serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
serde_yaml = { workspace = true, optional = true } serde_yaml = { workspace = true, optional = true }
subtle = { workspace = true, optional = true } subtle = { workspace = true, optional = true }
time = { workspace = true, optional = true, features = ["macros"] } time = { workspace = true, optional = true, features = ["macros"] }
@@ -7,7 +7,6 @@ use axum::http::{header, HeaderValue};
use axum::response::{IntoResponse, Response}; use axum::response::{IntoResponse, Response};
use bytes::{BufMut, BytesMut}; use bytes::{BufMut, BytesMut};
use serde::Serialize; use serde::Serialize;
use utoipa::gen::serde_json;
// don't use axum's Json directly as we need to be able to define custom headers // don't use axum's Json directly as we need to be able to define custom headers
#[derive(Debug, Clone, Default)] #[derive(Debug, Clone, Default)]
+1 -1
View File
@@ -191,7 +191,7 @@ impl fmt::Display for IpPacketRequestData {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
IpPacketRequestData::Data(_) => write!(f, "Data"), IpPacketRequestData::Data(_) => write!(f, "Data"),
IpPacketRequestData::Control(c) => write!(f, "Control({})", c), IpPacketRequestData::Control(c) => write!(f, "Control({c})"),
} }
} }
} }
+4 -6
View File
@@ -30,7 +30,7 @@ fn main() {
for var in variables_to_track { for var in variables_to_track {
// if script fails, debug with `cargo check -vv`` // if script fails, debug with `cargo check -vv``
println!("Looking for {}", var); println!("Looking for {var}");
// read pattern that looks like: // read pattern that looks like:
// <var>: &str = "<whatever is between quotes>" // <var>: &str = "<whatever is between quotes>"
@@ -41,7 +41,7 @@ fn main() {
.captures(source_of_truth) .captures(source_of_truth)
.and_then(|caps| caps.get(1).map(|match_| match_.as_str().to_string())) .and_then(|caps| caps.get(1).map(|match_| match_.as_str().to_string()))
.expect("Couldn't find var in source file"); .expect("Couldn't find var in source file");
println!("Storing {}={}", var, value); println!("Storing {var}={value}");
replace_with.insert(var, value); replace_with.insert(var, value);
} }
@@ -57,13 +57,11 @@ fn main() {
// <var>=<value> // <var>=<value>
let re = Regex::new(&pattern).unwrap(); let re = Regex::new(&pattern).unwrap();
contents = re contents = re
.replace(&contents, |_: &regex::Captures| { .replace(&contents, |_: &regex::Captures| format!(r#"{var}={value}"#))
format!(r#"{}={}"#, var, value)
})
.to_string(); .to_string();
} }
println!("File contents to write:\n{}", contents); println!("File contents to write:\n{contents}");
if output_path.exists() { if output_path.exists() {
fs::write(output_path, contents).unwrap(); fs::write(output_path, contents).unwrap();
} else { } else {
+1 -1
View File
@@ -25,7 +25,7 @@ fn print_env_vars_with_keys_in_file<P: AsRef<Path> + Copy>(config_env_file: P) {
.expect("Invalid path to environment configuration file"); .expect("Invalid path to environment configuration file");
for item in items { for item in items {
let (key, val) = item.expect("Invalid item in environment configuration file"); let (key, val) = item.expect("Invalid item in environment configuration file");
log::debug!("{}: {}", key, val); log::debug!("{key}: {val}");
} }
} }
+1 -1
View File
@@ -119,7 +119,7 @@ impl NymNetworkDetails {
} }
} }
Err(VarError::NotPresent) => None, Err(VarError::NotPresent) => None,
err => panic!("Unable to set: {:?}", err), err => panic!("Unable to set: {err:?}"),
} }
} }
+3 -3
View File
@@ -344,9 +344,9 @@ impl fmt::Display for MetricsController {
let metrics = self.gather(); let metrics = self.gather();
let output = match String::from_utf8(metrics) { let output = match String::from_utf8(metrics) {
Ok(output) => output, Ok(output) => output,
Err(e) => return write!(f, "Error decoding metrics to String: {}", e), Err(e) => return write!(f, "Error decoding metrics to String: {e}"),
}; };
write!(f, "{}", output) write!(f, "{output}")
} }
} }
@@ -597,7 +597,7 @@ mod tests {
assert_eq!(literal, "nym_metrics_foo"); assert_eq!(literal, "nym_metrics_foo");
let bar = "bar"; let bar = "bar";
let format = format!("foomp_{}", bar); let format = format!("foomp_{bar}");
let formatted = prepend_package_name!(format); let formatted = prepend_package_name!(format);
assert_eq!(formatted, "nym_metrics_foomp_bar"); assert_eq!(formatted, "nym_metrics_foomp_bar");
} }
@@ -26,7 +26,7 @@ impl GroupParameters {
pub fn new(attributes: usize) -> GroupParameters { pub fn new(attributes: usize) -> GroupParameters {
assert!(attributes > 0); assert!(attributes > 0);
let gammas = (1..=attributes) let gammas = (1..=attributes)
.map(|i| hash_g1(format!("gamma{}", i))) .map(|i| hash_g1(format!("gamma{i}")))
.collect(); .collect();
let delta = hash_g1("delta"); let delta = hash_g1("delta");
@@ -56,6 +56,13 @@ impl ReplySurb {
packet_size.plaintext_size() - ack_overhead - ReplySurbKeyDigestAlgorithm::output_size() - 1 packet_size.plaintext_size() - ack_overhead - ReplySurbKeyDigestAlgorithm::output_size() - 1
} }
/// Construct a ResplySurb object. Selects mix hops for the surb unique to this
/// individual construction.
///
/// If mix hops are disabled, the route will consistency of the recipient
/// (i.e. the ingress hop) only. When `disable_mix_hops` is enabled
/// `use_legacy_surb_format` is ignored as disabled mix hops requires use of
/// the updated SURB format.
// TODO: should this return `ReplySURBError` for consistency sake // TODO: should this return `ReplySURBError` for consistency sake
// or keep `NymTopologyError` because it's the only error it can actually return? // or keep `NymTopologyError` because it's the only error it can actually return?
pub fn construct<R>( pub fn construct<R>(
@@ -64,17 +71,21 @@ impl ReplySurb {
average_delay: Duration, average_delay: Duration,
use_legacy_surb_format: bool, use_legacy_surb_format: bool,
topology: &NymRouteProvider, topology: &NymRouteProvider,
_disable_mix_hops: bool, // TODO: support SURBs with no mix hops after changes to surb format / construction disable_mix_hops: bool,
) -> Result<Self, NymTopologyError> ) -> Result<Self, NymTopologyError>
where where
R: RngCore + CryptoRng, R: RngCore + CryptoRng,
{ {
let route = topology.random_route_to_egress(rng, recipient.gateway())?; let route = if disable_mix_hops {
topology.empty_route_to_egress(recipient.gateway())?
} else {
topology.random_route_to_egress(rng, recipient.gateway())?
};
let delays = nym_sphinx_routing::generate_hop_delays(average_delay, route.len()); let delays = nym_sphinx_routing::generate_hop_delays(average_delay, route.len());
let destination = recipient.as_sphinx_destination(); let destination = recipient.as_sphinx_destination();
let mut surb_material = SURBMaterial::new(route, delays, destination); let mut surb_material = SURBMaterial::new(route, delays, destination);
if use_legacy_surb_format { if use_legacy_surb_format && !disable_mix_hops {
surb_material = surb_material.with_version(X25519_WITH_EXPLICIT_PAYLOAD_KEYS_VERSION) surb_material = surb_material.with_version(X25519_WITH_EXPLICIT_PAYLOAD_KEYS_VERSION)
} }
+4 -1
View File
@@ -335,6 +335,9 @@ pub struct MessagePreparer<R> {
/// will be routed as usual, to the entry gateway, through three mix nodes, egressing /// will be routed as usual, to the entry gateway, through three mix nodes, egressing
/// through the exit gateway. If mix hops are disabled, traffic will be routed directly /// through the exit gateway. If mix hops are disabled, traffic will be routed directly
/// from the entry gateway to the exit gateway, bypassing the mix nodes. /// from the entry gateway to the exit gateway, bypassing the mix nodes.
///
/// This overrides the `use_legacy_sphinx_format` setting as reduced/disabled mix hops
/// requires use of the updated SURB packet format.
pub disable_mix_hops: bool, pub disable_mix_hops: bool,
} }
@@ -388,7 +391,7 @@ where
self.average_packet_delay, self.average_packet_delay,
use_legacy_reply_surb_format, use_legacy_reply_surb_format,
topology, topology,
disabled_mix_hops, // TODO: support SURBs with no mix hops after changes to surb format / construction disabled_mix_hops,
)? )?
.with_key_rotation(key_rotation); .with_key_rotation(key_rotation);
reply_surbs.push(reply_surb) reply_surbs.push(reply_surb)
+2 -2
View File
@@ -197,7 +197,7 @@ where
let res = tokio::select! { let res = tokio::select! {
biased; biased;
message = receiver.next() => { message = receiver.next() => {
log::debug!("Received message: {:?}", message); log::debug!("Received message: {message:?}");
match message { match message {
Some(Socks5ControlMessage::Stop) => { Some(Socks5ControlMessage::Stop) => {
log::info!("Received stop message"); log::info!("Received stop message");
@@ -209,7 +209,7 @@ where
Ok(()) Ok(())
} }
Some(msg) = shutdown.wait_for_error() => { Some(msg) = shutdown.wait_for_error() => {
log::info!("Task error: {:?}", msg); log::info!("Task error: {msg:?}");
Err(msg) Err(msg)
} }
_ = tokio::signal::ctrl_c() => { _ = tokio::signal::ctrl_c() => {
@@ -579,7 +579,7 @@ impl SocksClient {
); );
// Get valid auth methods // Get valid auth methods
let methods = self.get_available_methods().await?; let methods = self.get_available_methods().await?;
trace!("methods: {:?}", methods); trace!("methods: {methods:?}");
let mut response = [0u8; 2]; let mut response = [0u8; 2];
@@ -61,7 +61,7 @@ impl MixnetResponseListener {
control_response: ControlResponse, control_response: ControlResponse,
) -> Result<(), Socks5ClientCoreError> { ) -> Result<(), Socks5ClientCoreError> {
error!("received a control response which we don't know how to handle yet!"); error!("received a control response which we don't know how to handle yet!");
error!("got: {:?}", control_response); error!("got: {control_response:?}");
// I guess we'd need another channel here to forward those to where they need to go // I guess we'd need another channel here to forward those to where they need to go
@@ -88,7 +88,7 @@ impl MixnetResponseListener {
} }
Socks5ResponseContent::Query(response) => { Socks5ResponseContent::Query(response) => {
error!("received a query response which we don't know how to handle yet!"); error!("received a query response which we don't know how to handle yet!");
error!("got: {:?}", response); error!("got: {response:?}");
// I guess we'd need another channel here to forward those to where they need to go // I guess we'd need another channel here to forward those to where they need to go
@@ -122,8 +122,7 @@ where
biased; biased;
_ = &mut shutdown_future => { _ = &mut shutdown_future => {
debug!( debug!(
"closing inbound proxy after outbound was closed {:?} ago", "closing inbound proxy after outbound was closed {SHUTDOWN_TIMEOUT:?} ago"
SHUTDOWN_TIMEOUT
); );
// inform remote just in case it was closed because of lack of heartbeat. // inform remote just in case it was closed because of lack of heartbeat.
// worst case the remote will just have couple of false negatives // worst case the remote will just have couple of false negatives
@@ -169,7 +168,7 @@ where
} }
} }
} }
trace!("{} - inbound closed", connection_id); trace!("{connection_id} - inbound closed");
shutdown_notify.notify_one(); shutdown_notify.notify_one();
shutdown_listener.disarm(); shutdown_listener.disarm();
@@ -72,12 +72,12 @@ pub(super) async fn run_outbound(
} }
} }
_ = &mut mix_timeout => { _ = &mut mix_timeout => {
warn!("didn't get anything from the client on {} mixnet in {:?}. Shutting down the proxy.", connection_id, MIX_TTL); warn!("didn't get anything from the client on {connection_id} mixnet in {MIX_TTL:?}. Shutting down the proxy.");
// If they were online it's kinda their fault they didn't send any heartbeat messages. // If they were online it's kinda their fault they didn't send any heartbeat messages.
break; break;
} }
_ = &mut shutdown_future => { _ = &mut shutdown_future => {
debug!("closing outbound proxy after inbound was closed {:?} ago", SHUTDOWN_TIMEOUT); debug!("closing outbound proxy after inbound was closed {SHUTDOWN_TIMEOUT:?} ago");
break; break;
} }
_ = shutdown_listener.recv() => { _ = shutdown_listener.recv() => {
@@ -87,7 +87,7 @@ pub(super) async fn run_outbound(
} }
} }
trace!("{} - outbound closed", connection_id); trace!("{connection_id} - outbound closed");
shutdown_notify.notify_one(); shutdown_notify.notify_one();
shutdown_listener.disarm(); shutdown_listener.disarm();
+1 -1
View File
@@ -360,7 +360,7 @@ impl Socks5RequestContent {
let query_bytes: Vec<u8> = make_bincode_serializer() let query_bytes: Vec<u8> = make_bincode_serializer()
.serialize(&query) .serialize(&query)
.tap_err(|err| { .tap_err(|err| {
log::error!("Failed to serialize query request: {:?}: {err}", query); log::error!("Failed to serialize query request: {query:?}: {err}");
}) })
.unwrap_or_default(); .unwrap_or_default();
std::iter::once(RequestFlag::Query as u8) std::iter::once(RequestFlag::Query as u8)
+1 -1
View File
@@ -213,7 +213,7 @@ impl Socks5ResponseContent {
let query_bytes: Vec<u8> = make_bincode_serializer() let query_bytes: Vec<u8> = make_bincode_serializer()
.serialize(&query) .serialize(&query)
.tap_err(|err| { .tap_err(|err| {
log::error!("Failed to serialize query response: {:?}: {err}", query); log::error!("Failed to serialize query response: {query:?}: {err}");
}) })
.unwrap_or_default(); .unwrap_or_default();
std::iter::once(ResponseFlag::Query as u8) std::iter::once(ResponseFlag::Query as u8)
@@ -77,7 +77,7 @@ impl GatewayStatsControl {
fn report_counters(&self) { fn report_counters(&self) {
log::trace!("packet statistics: {:?}", &self.stats); log::trace!("packet statistics: {:?}", &self.stats);
let (summary_sent, summary_recv) = self.stats.summary(); let (summary_sent, summary_recv) = self.stats.summary();
log::debug!("{}", summary_sent); log::debug!("{summary_sent}");
log::debug!("{}", summary_recv); log::debug!("{summary_recv}");
} }
} }
@@ -77,7 +77,7 @@ impl NymApiStatsControl {
fn report_counters(&self) { fn report_counters(&self) {
log::trace!("packet statistics: {:?}", &self.stats); log::trace!("packet statistics: {:?}", &self.stats);
let (summary_sent, summary_recv) = self.stats.summary(); let (summary_sent, summary_recv) = self.stats.summary();
log::debug!("{}", summary_sent); log::debug!("{summary_sent}");
log::debug!("{}", summary_recv); log::debug!("{summary_recv}");
} }
} }
@@ -529,8 +529,8 @@ impl PacketStatisticsControl {
fn report_counters(&self) { fn report_counters(&self) {
log::trace!("packet statistics: {:?}", &self.stats); log::trace!("packet statistics: {:?}", &self.stats);
let (summary_sent, summary_recv) = self.stats.summary(); let (summary_sent, summary_recv) = self.stats.summary();
log::debug!("{}", summary_sent); log::debug!("{summary_sent}");
log::debug!("{}", summary_recv); log::debug!("{summary_recv}");
} }
fn check_for_notable_events(&self) { fn check_for_notable_events(&self) {

Some files were not shown because too many files have changed in this diff Show More