diff --git a/common/authenticator-requests/src/v3/request.rs b/common/authenticator-requests/src/v3/request.rs index fab1784695..61e0914c1d 100644 --- a/common/authenticator-requests/src/v3/request.rs +++ b/common/authenticator-requests/src/v3/request.rs @@ -95,7 +95,7 @@ pub enum AuthenticatorRequestData { Initial(InitMessage), Final(Box), QueryBandwidth(PeerPublicKey), - TopUpBandwidth(TopUpMessage), + TopUpBandwidth(Box), } #[cfg(test)] diff --git a/common/authenticator-requests/src/v3/response.rs b/common/authenticator-requests/src/v3/response.rs index 0c09891f47..370fc64671 100644 --- a/common/authenticator-requests/src/v3/response.rs +++ b/common/authenticator-requests/src/v3/response.rs @@ -1,10 +1,7 @@ // Copyright 2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use super::{ - registration::{RegistrationData, RegistredData, RemainingBandwidthData}, - topup::TopUpBandwidthData, -}; +use super::registration::{RegistrationData, RegistredData, RemainingBandwidthData}; use nym_service_provider_requests_common::{Protocol, ServiceProviderType}; use nym_sphinx::addressing::Recipient; use serde::{Deserialize, Serialize}; @@ -79,7 +76,7 @@ impl AuthenticatorResponse { } pub fn new_topup_bandwidth( - remaining_bandwidth_data: TopUpBandwidthData, + remaining_bandwidth_data: RemainingBandwidthData, reply_to: Recipient, request_id: u64, ) -> Self { @@ -156,5 +153,5 @@ pub struct RemainingBandwidthResponse { pub struct TopUpBandwidthResponse { pub request_id: u64, pub reply_to: Recipient, - pub reply: TopUpBandwidthData, + pub reply: RemainingBandwidthData, } diff --git a/common/authenticator-requests/src/v3/topup.rs b/common/authenticator-requests/src/v3/topup.rs index 57e6924e6a..31a61a0659 100644 --- a/common/authenticator-requests/src/v3/topup.rs +++ b/common/authenticator-requests/src/v3/topup.rs @@ -13,6 +13,3 @@ pub struct TopUpMessage { /// Ecash credential pub credential: CredentialSpendingData, } - -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct TopUpBandwidthData {} diff --git a/service-providers/authenticator/src/error.rs b/service-providers/authenticator/src/error.rs index 32ee7fb439..bfc04c3fbc 100644 --- a/service-providers/authenticator/src/error.rs +++ b/service-providers/authenticator/src/error.rs @@ -79,6 +79,15 @@ pub enum AuthenticatorError { #[error("peers can't be interacted with anymore")] PeerInteractionStopped, + + #[error("operation is not supported")] + UnsupportedOperation, + + #[error("operation unavailable for older client")] + OldClient, + + #[error("storage should have the requested bandwidht entry")] + MissingClientBandwidthEntry, } pub type Result = std::result::Result; diff --git a/service-providers/authenticator/src/mixnet_listener.rs b/service-providers/authenticator/src/mixnet_listener.rs index bae4dd6eb5..6a98dd7426 100644 --- a/service-providers/authenticator/src/mixnet_listener.rs +++ b/service-providers/authenticator/src/mixnet_listener.rs @@ -15,18 +15,17 @@ use nym_authenticator_requests::{ self, registration::{ FinalMessage, GatewayClient, InitMessage, PendingRegistrations, PrivateIPs, - RegistrationData, RegistredData, + RegistrationData, RegistredData, RemainingBandwidthData, }, request::{AuthenticatorRequest, AuthenticatorRequestData}, response::AuthenticatorResponse, - topup::TopUpBandwidthData, }, }; use nym_credential_verification::{ bandwidth_storage_manager::BandwidthStorageManager, ecash::EcashManager, BandwidthFlushingBehaviourConfig, ClientBandwidth, CredentialVerifier, }; -use nym_credentials_interface::CredentialSpendingData; +use nym_credentials_interface::{CredentialSpendingData, TicketType}; use nym_crypto::asymmetric::x25519::KeyPair; use nym_gateway_requests::models::CredentialSpendingRequest; use nym_gateway_storage::Storage; @@ -335,9 +334,56 @@ impl MixnetListener { request_id: u64, reply_to: Recipient, ) -> AuthenticatorHandleResult { - let bandwidth_data = self.peer_manager.query_bandwidth(peer_public_key).await?; + let Some(ecash_verifier) = self.ecash_verifier.clone() else { + return Err(AuthenticatorError::UnsupportedOperation); + }; + let client_id = ecash_verifier + .storage() + .get_wireguard_peer(&peer_public_key.to_string()) + .await? + .ok_or(AuthenticatorError::MissingClientBandwidthEntry)? + .client_id + .ok_or(AuthenticatorError::OldClient)?; + let bandwidth = ecash_verifier + .storage() + .get_available_bandwidth(client_id) + .await? + .ok_or(AuthenticatorError::InternalError( + "bandwidth entry should have just been created".to_string(), + ))?; + + let t_type = credential.payment.t_type; + let client_bandwidth = ClientBandwidth::new(bandwidth.into()); + let mut verifier = CredentialVerifier::new( + CredentialSpendingRequest::new(credential), + ecash_verifier.clone(), + BandwidthStorageManager::new( + ecash_verifier.storage().clone(), + client_bandwidth, + client_id, + BandwidthFlushingBehaviourConfig::default(), + true, + ), + ); + verifier.verify().await?; + + let amount = TicketType::try_from_encoded(t_type) + .map_err(|e| { + AuthenticatorError::CredentialVerificationError( + nym_credential_verification::Error::UnknownTicketType(e), + ) + })? + .to_repr() + .bandwidth_value() as i64; + let available_bandwidth = ecash_verifier + .storage() + .increase_bandwidth(client_id, amount) + .await?; + Ok(AuthenticatorResponse::new_topup_bandwidth( - TopUpBandwidthData {}, + RemainingBandwidthData { + available_bandwidth, + }, reply_to, request_id, ))