gateway handling of both credential types

This commit is contained in:
Jędrzej Stuczyński
2024-02-07 17:21:29 +00:00
parent 675cf3d7da
commit 0ee727bac1
4 changed files with 69 additions and 37 deletions
+3
View File
@@ -457,6 +457,9 @@ pub const ETH_ERC20_APPROVE_FUNCTION_NAME: &str = "approve";
/// How much bandwidth (in bytes) one token can buy
pub const BYTES_PER_UTOKEN: u64 = 1024;
/// How much bandwidth (in bytes) one freepass provides
pub const BYTES_PER_FREEPASS: u64 = 1024 * 1024 * 1024; // 1GB
/// Threshold for claiming more bandwidth: 1 MB
pub const REMAINING_BANDWIDTH_THRESHOLD: i64 = 1024 * 1024;
/// How many ERC20 tokens should be burned to buy bandwidth
+1
View File
@@ -55,6 +55,7 @@ tokio-stream = { version = "0.1.11", features = ["fs"] }
tokio-tungstenite = { version = "0.20.1" }
tokio-util = { workspace = true, features = ["codec"] }
url = { workspace = true, features = ["serde"] }
time = { workspace = true }
zeroize = { workspace = true }
# internal
+62 -29
View File
@@ -1,12 +1,40 @@
// Copyright 2021-2024 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only
use log::error;
use log::{error, warn};
use nym_credentials::coconut::bandwidth::CredentialType;
use std::num::ParseIntError;
use thiserror::Error;
use time::error::ComponentRange;
use time::OffsetDateTime;
#[derive(Debug, Error)]
pub enum BandwidthError {}
pub enum BandwidthError {
#[error("Provided bandwidth credential asks for more bandwidth than it is supported to add at once (credential value: {0}, supported: {}). Try to split it before attempting again", i64::MAX)]
UnsupportedBandwidthValue(u64),
#[error("the provided free pass has already expired (expiry was on {expiry_date})")]
ExpiredFreePass { expiry_date: OffsetDateTime },
#[error("failed to pass the bandwidth voucher value: {source}")]
VoucherValueParsingFailure {
#[source]
source: ParseIntError,
},
#[error("failed to pass the free pass expiry date: {source}")]
ExpiryDateParsingFailure {
#[source]
source: ParseIntError,
},
#[error("failed to parse expiry timestamp into proper datetime: {source}")]
InvalidExpiryDate {
unix_timestamp: i64,
#[source]
source: ComponentRange,
},
}
pub struct Bandwidth {
value: u64,
@@ -18,42 +46,47 @@ impl Bandwidth {
}
pub fn try_from_raw_value(value: &String, typ: CredentialType) -> Result<Self, BandwidthError> {
// let bandwidth_value = match credential.data.typ {
// CredentialType::Voucher => {
// todo!()
// }
// CredentialType::FreePass => {
// error!("unimplemented handling of free pass credential");
// return Err(());
// }
// };
let bandwidth_value =
match typ {
CredentialType::Voucher => {
let token_value: u64 = value
.parse()
.map_err(|source| BandwidthError::VoucherValueParsingFailure { source })?;
token_value * nym_network_defaults::BYTES_PER_UTOKEN
}
CredentialType::FreePass => {
let expiry_timestamp: i64 = value
.parse()
.map_err(|source| BandwidthError::ExpiryDateParsingFailure { source })?;
/*
if bandwidth_value > i64::MAX as u64 {
let expiry_date = OffsetDateTime::from_unix_timestamp(expiry_timestamp)
.map_err(|source| BandwidthError::InvalidExpiryDate {
unix_timestamp: expiry_timestamp,
source,
})?;
let now = OffsetDateTime::now_utc();
if expiry_date < now {
return Err(BandwidthError::ExpiredFreePass { expiry_date });
}
nym_network_defaults::BYTES_PER_FREEPASS
}
};
if bandwidth_value > i64::MAX as u64 {
// note that this would have represented more than 1 exabyte,
// which is like 125,000 worth of hard drives so I don't think we have
// which is like 125,000 worth of hard drives, so I don't think we have
// to worry about it for now...
warn!("Somehow we received bandwidth value higher than 9223372036854775807. We don't really want to deal with this now");
return Err(RequestHandlingError::UnsupportedBandwidthValue(
bandwidth_value,
));
return Err(BandwidthError::UnsupportedBandwidthValue(bandwidth_value));
}
*/
todo!()
Ok(Bandwidth {
value: bandwidth_value,
})
}
pub fn value(&self) -> u64 {
self.value
}
}
// impl From<Credential> for Bandwidth {
// fn from(credential: Credential) -> Self {
// let token_value = credential.voucher_value();
// let bandwidth_bytes = token_value * nym_network_defaults::BYTES_PER_UTOKEN;
// Bandwidth {
// value: bandwidth_bytes,
// }
// }
// }
@@ -53,9 +53,6 @@ pub(crate) enum RequestHandlingError {
#[error("The received request is not valid in the current context")]
IllegalRequest,
#[error("Provided bandwidth credential asks for more bandwidth than it is supported to add at once (credential value: {0}, supported: {}). Try to split it before attempting again", i64::MAX)]
UnsupportedBandwidthValue(u64),
#[error("Provided bandwidth credential did not verify correctly on {0}")]
InvalidBandwidthCredential(String),
@@ -85,9 +82,6 @@ pub(crate) enum RequestHandlingError {
#[error("failed to recover bandwidth value: {0}")]
BandwidthRecoveryFailure(#[from] BandwidthError),
#[error("free pass credentials haven't been implemented yet")]
UnimplementedFreePass,
}
impl RequestHandlingError {
@@ -250,6 +244,7 @@ where
unimplemented!()
};
// this will extract token amounts out of bandwidth vouchers and validate expiry of free passes
let bandwidth = Bandwidth::try_from_raw_value(bandwidth_attribute, credential.data.typ)?;
let params = bandwidth_credential_params();
@@ -273,8 +268,8 @@ where
.await?;
}
CredentialType::FreePass => {
error!("unimplemented handling of free pass credential");
return Err(RequestHandlingError::UnimplementedFreePass);
// no need to do anything special here, we already extracted the bandwidth amount and checked expiry
info!("received a free pass credential");
}
}