From 6d1df8e52a32f452c3e7dadf41aef4c25580585b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogdan-=C8=98tefan=20Neac=C5=9Fu?= Date: Wed, 16 Oct 2024 10:32:02 +0300 Subject: [PATCH] Introduce v3 with top up --- common/authenticator-requests/src/error.rs | 3 ++ .../src/v3/conversion.rs | 43 ++++++++++----- .../authenticator-requests/src/v3/response.rs | 33 +++++++++++- common/authenticator-requests/src/v3/topup.rs | 5 +- .../commands/src/ecash/import_ticket_book.rs | 18 +------ common/wireguard/src/peer_controller.rs | 2 +- .../authenticator/src/mixnet_listener.rs | 53 +++++++++++++++---- .../authenticator/src/peer_manager.rs | 2 +- 8 files changed, 116 insertions(+), 43 deletions(-) diff --git a/common/authenticator-requests/src/error.rs b/common/authenticator-requests/src/error.rs index d07ad7c1e7..fc9f8700d5 100644 --- a/common/authenticator-requests/src/error.rs +++ b/common/authenticator-requests/src/error.rs @@ -19,4 +19,7 @@ pub enum Error { #[source] source: hmac::digest::MacError, }, + + #[error("conversion: {0}")] + Conversion(String), } diff --git a/common/authenticator-requests/src/v3/conversion.rs b/common/authenticator-requests/src/v3/conversion.rs index 8768759eed..15659271b2 100644 --- a/common/authenticator-requests/src/v3/conversion.rs +++ b/common/authenticator-requests/src/v3/conversion.rs @@ -84,32 +84,47 @@ impl From for v2::registration::ClientMac { } } -impl From for v2::response::AuthenticatorResponse { - fn from(authenticator_response: v3::response::AuthenticatorResponse) -> Self { - Self { - data: authenticator_response.data.into(), +impl TryFrom for v2::response::AuthenticatorResponse { + type Error = crate::Error; + + fn try_from( + authenticator_response: v3::response::AuthenticatorResponse, + ) -> Result { + Ok(Self { + data: authenticator_response.data.try_into()?, reply_to: authenticator_response.reply_to, protocol: authenticator_response.protocol, - } + }) } } -impl From for v2::response::AuthenticatorResponseData { - fn from(authenticator_response_data: v3::response::AuthenticatorResponseData) -> Self { +impl TryFrom for v2::response::AuthenticatorResponseData { + type Error = crate::Error; + + fn try_from( + authenticator_response_data: v3::response::AuthenticatorResponseData, + ) -> Result { match authenticator_response_data { v3::response::AuthenticatorResponseData::PendingRegistration( pending_registration_response, - ) => v2::response::AuthenticatorResponseData::PendingRegistration( - pending_registration_response.into(), + ) => Ok( + v2::response::AuthenticatorResponseData::PendingRegistration( + pending_registration_response.into(), + ), + ), + v3::response::AuthenticatorResponseData::Registered(registered_response) => Ok( + v2::response::AuthenticatorResponseData::Registered(registered_response.into()), ), - v3::response::AuthenticatorResponseData::Registered(registered_response) => { - v2::response::AuthenticatorResponseData::Registered(registered_response.into()) - } v3::response::AuthenticatorResponseData::RemainingBandwidth( remaining_bandwidth_response, - ) => v2::response::AuthenticatorResponseData::RemainingBandwidth( + ) => Ok(v2::response::AuthenticatorResponseData::RemainingBandwidth( remaining_bandwidth_response.into(), - ), + )), + v3::response::AuthenticatorResponseData::TopUpBandwidth(_) => { + Err(Self::Error::Conversion( + "a v2 request couldn't produce a v3 only type of response".to_string(), + )) + } } } } diff --git a/common/authenticator-requests/src/v3/response.rs b/common/authenticator-requests/src/v3/response.rs index ab05dfcd35..0c09891f47 100644 --- a/common/authenticator-requests/src/v3/response.rs +++ b/common/authenticator-requests/src/v3/response.rs @@ -1,7 +1,10 @@ // Copyright 2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use super::registration::{RegistrationData, RegistredData, RemainingBandwidthData}; +use super::{ + registration::{RegistrationData, RegistredData, RemainingBandwidthData}, + topup::TopUpBandwidthData, +}; use nym_service_provider_requests_common::{Protocol, ServiceProviderType}; use nym_sphinx::addressing::Recipient; use serde::{Deserialize, Serialize}; @@ -75,6 +78,25 @@ impl AuthenticatorResponse { } } + pub fn new_topup_bandwidth( + remaining_bandwidth_data: TopUpBandwidthData, + reply_to: Recipient, + request_id: u64, + ) -> Self { + Self { + protocol: Protocol { + service_provider_type: ServiceProviderType::Authenticator, + version: VERSION, + }, + data: AuthenticatorResponseData::TopUpBandwidth(TopUpBandwidthResponse { + reply: remaining_bandwidth_data, + reply_to, + request_id, + }), + reply_to, + } + } + pub fn recipient(&self) -> Recipient { self.reply_to } @@ -96,6 +118,7 @@ impl AuthenticatorResponse { AuthenticatorResponseData::PendingRegistration(response) => Some(response.request_id), AuthenticatorResponseData::Registered(response) => Some(response.request_id), AuthenticatorResponseData::RemainingBandwidth(response) => Some(response.request_id), + AuthenticatorResponseData::TopUpBandwidth(response) => Some(response.request_id), } } } @@ -105,6 +128,7 @@ pub enum AuthenticatorResponseData { PendingRegistration(PendingRegistrationResponse), Registered(RegisteredResponse), RemainingBandwidth(RemainingBandwidthResponse), + TopUpBandwidth(TopUpBandwidthResponse), } #[derive(Clone, Debug, Serialize, Deserialize)] @@ -127,3 +151,10 @@ pub struct RemainingBandwidthResponse { pub reply_to: Recipient, pub reply: Option, } + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub struct TopUpBandwidthResponse { + pub request_id: u64, + pub reply_to: Recipient, + pub reply: TopUpBandwidthData, +} diff --git a/common/authenticator-requests/src/v3/topup.rs b/common/authenticator-requests/src/v3/topup.rs index ef1f144533..57e6924e6a 100644 --- a/common/authenticator-requests/src/v3/topup.rs +++ b/common/authenticator-requests/src/v3/topup.rs @@ -11,5 +11,8 @@ pub struct TopUpMessage { pub pub_key: PeerPublicKey, /// Ecash credential - pub credential: Option, + pub credential: CredentialSpendingData, } + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct TopUpBandwidthData {} diff --git a/common/commands/src/ecash/import_ticket_book.rs b/common/commands/src/ecash/import_ticket_book.rs index 2c5d597659..c967943239 100644 --- a/common/commands/src/ecash/import_ticket_book.rs +++ b/common/commands/src/ecash/import_ticket_book.rs @@ -31,7 +31,7 @@ impl FromStr for CredentialDataWrapper { pub struct Args { /// Config file of the client that is supposed to use the credential. #[clap(long)] - pub(crate) client_config: PathBuf, + pub(crate) credentials_store: PathBuf, /// Explicitly provide the encoded credential data (as base58) #[clap(long, group = "cred_data")] @@ -70,21 +70,7 @@ impl Args { } pub async fn execute(args: Args) -> anyhow::Result<()> { - let loaded = CommonConfigsWrapper::try_load(&args.client_config)?; - - if let Ok(id) = loaded.try_get_id() { - println!("loaded config file for client '{id}'"); - } - - let Ok(credentials_store) = loaded.try_get_credentials_store() else { - bail!("the loaded config does not have a credentials store information") - }; - - println!( - "using credentials store at '{}'", - credentials_store.display() - ); - let credentials_store = initialise_persistent_storage(credentials_store).await; + let credentials_store = initialise_persistent_storage(args.credentials_store.clone()).await; let version = args.version; let standalone = args.standalone; diff --git a/common/wireguard/src/peer_controller.rs b/common/wireguard/src/peer_controller.rs index 9bc49b883b..c6316a720e 100644 --- a/common/wireguard/src/peer_controller.rs +++ b/common/wireguard/src/peer_controller.rs @@ -8,7 +8,7 @@ use defguard_wireguard_rs::{ }; use futures::channel::oneshot; use nym_authenticator_requests::{ - v1::registration::BANDWIDTH_CAP_PER_DAY, v2::registration::RemainingBandwidthData, + latest::registration::RemainingBandwidthData, v1::registration::BANDWIDTH_CAP_PER_DAY, }; use nym_credential_verification::{ bandwidth_storage_manager::BandwidthStorageManager, BandwidthFlushingBehaviourConfig, diff --git a/service-providers/authenticator/src/mixnet_listener.rs b/service-providers/authenticator/src/mixnet_listener.rs index 05c80cd496..bae4dd6eb5 100644 --- a/service-providers/authenticator/src/mixnet_listener.rs +++ b/service-providers/authenticator/src/mixnet_listener.rs @@ -9,18 +9,17 @@ use std::{ use crate::{error::AuthenticatorError, peer_manager::PeerManager}; use futures::StreamExt; use log::warn; -use nym_authenticator_requests::v2::{ - self, - registration::{ - FinalMessage, GatewayClient, InitMessage, PendingRegistrations, PrivateIPs, - RegistrationData, RegistredData, - }, -}; use nym_authenticator_requests::{ - v1, - v2::{ + v1, v2, + v3::{ + self, + registration::{ + FinalMessage, GatewayClient, InitMessage, PendingRegistrations, PrivateIPs, + RegistrationData, RegistredData, + }, request::{AuthenticatorRequest, AuthenticatorRequestData}, response::AuthenticatorResponse, + topup::TopUpBandwidthData, }, }; use nym_credential_verification::{ @@ -329,6 +328,21 @@ impl MixnetListener { )) } + async fn on_topup_bandwidth_request( + &mut self, + peer_public_key: PeerPublicKey, + credential: CredentialSpendingData, + request_id: u64, + reply_to: Recipient, + ) -> AuthenticatorHandleResult { + let bandwidth_data = self.peer_manager.query_bandwidth(peer_public_key).await?; + Ok(AuthenticatorResponse::new_topup_bandwidth( + TopUpBandwidthData {}, + reply_to, + request_id, + )) + } + async fn on_reconstructed_message( &mut self, reconstructed: ReconstructedMessage, @@ -362,6 +376,15 @@ impl MixnetListener { ) .await } + AuthenticatorRequestData::TopUpBandwidth(topup_message) => { + self.on_topup_bandwidth_request( + topup_message.pub_key, + topup_message.credential, + request.request_id, + request.reply_to, + ) + .await + } } } @@ -440,6 +463,7 @@ fn deserialize_request(reconstructed: &ReconstructedMessage) -> Result v1::request::AuthenticatorRequest::from_reconstructed_message(reconstructed) .map_err(|err| AuthenticatorError::FailedToDeserializeTaggedPacket { source: err }) + .map(Into::::into) .map(Into::into), [2, request_type] => { if request_type == ServiceProviderType::Authenticator as u8 { @@ -452,6 +476,17 @@ fn deserialize_request(reconstructed: &ReconstructedMessage) -> Result { + if request_type == ServiceProviderType::Authenticator as u8 { + v3::request::AuthenticatorRequest::from_reconstructed_message(reconstructed) + .map_err(|err| AuthenticatorError::FailedToDeserializeTaggedPacket { + source: err, + }) + .map(Into::into) + } else { + Err(AuthenticatorError::InvalidPacketType(request_type)) + } + } [version, _] => { log::info!("Received packet with invalid version: v{version}"); Err(AuthenticatorError::InvalidPacketVersion(version)) diff --git a/service-providers/authenticator/src/peer_manager.rs b/service-providers/authenticator/src/peer_manager.rs index fbbdf6a06f..9d70036c9c 100644 --- a/service-providers/authenticator/src/peer_manager.rs +++ b/service-providers/authenticator/src/peer_manager.rs @@ -4,7 +4,7 @@ use crate::error::*; use defguard_wireguard_rs::{host::Peer, key::Key, net::IpAddrMask}; use futures::channel::oneshot; -use nym_authenticator_requests::v2::registration::{GatewayClient, RemainingBandwidthData}; +use nym_authenticator_requests::latest::registration::{GatewayClient, RemainingBandwidthData}; use nym_wireguard::{ peer_controller::{ AddPeerControlResponse, PeerControlRequest, QueryBandwidthControlResponse,