Skip to content

Commit

Permalink
Use ticket type when retrieving from storage (#4947)
Browse files Browse the repository at this point in the history
  • Loading branch information
neacsu authored Oct 14, 2024
1 parent 08aa0af commit 8758bea
Show file tree
Hide file tree
Showing 11 changed files with 37 additions and 11 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 8 additions & 4 deletions common/bandwidth-controller/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use nym_credential_storage::models::RetrievedTicketbook;
use nym_credential_storage::storage::Storage;
use nym_credentials::ecash::bandwidth::CredentialSpendingData;
use nym_credentials_interface::{
AnnotatedCoinIndexSignature, AnnotatedExpirationDateSignature, VerificationKeyAuth,
AnnotatedCoinIndexSignature, AnnotatedExpirationDateSignature, TicketType, VerificationKeyAuth,
};
use nym_ecash_time::Date;
use nym_validator_client::nym_api::EpochId;
Expand Down Expand Up @@ -64,17 +64,18 @@ impl<C, St: Storage> BandwidthController<C, St> {
BandwidthController { storage, client }
}

/// Tries to retrieve one of the stored, unused credentials that hasn't yet expired.
/// Tries to retrieve one of the stored, unused credentials for the given type that hasn't yet expired.
pub async fn get_next_usable_ticketbook(
&self,
ticketbook_type: TicketType,
tickets: u32,
) -> Result<RetrievedTicketbook, BandwidthControllerError>
where
<St as Storage>::StorageError: Send + Sync + 'static,
{
let Some(ticketbook) = self
.storage
.get_next_unspent_usable_ticketbook(tickets)
.get_next_unspent_usable_ticketbook(ticketbook_type.to_string(), tickets)
.await
.map_err(BandwidthControllerError::credential_storage_error)?
else {
Expand Down Expand Up @@ -181,14 +182,17 @@ impl<C, St: Storage> BandwidthController<C, St> {

pub async fn prepare_ecash_ticket(
&self,
ticketbook_type: TicketType,
provider_pk: [u8; 32],
tickets_to_spend: u32,
) -> Result<PreparedCredential, BandwidthControllerError>
where
C: DkgQueryClient + Sync + Send,
<St as Storage>::StorageError: Send + Sync + 'static,
{
let retrieved_ticketbook = self.get_next_usable_ticketbook(tickets_to_spend).await?;
let retrieved_ticketbook = self
.get_next_usable_ticketbook(ticketbook_type, tickets_to_spend)
.await?;

let ticketbook_id = retrieved_ticketbook.ticketbook_id;
let epoch_id = retrieved_ticketbook.ticketbook.epoch_id();
Expand Down
1 change: 1 addition & 0 deletions common/client-libs/gateway-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ zeroize.workspace = true
nym-bandwidth-controller = { path = "../../bandwidth-controller" }
nym-credentials = { path = "../../credentials" }
nym-credential-storage = { path = "../../credential-storage" }
nym-credentials-interface = { path = "../../credentials-interface" }
nym-crypto = { path = "../../crypto" }
nym-gateway-requests = { path = "../../gateway-requests" }
nym-network-defaults = { path = "../../network-defaults" }
Expand Down
7 changes: 6 additions & 1 deletion common/client-libs/gateway-client/src/client/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use nym_bandwidth_controller::{BandwidthController, BandwidthStatusMessage};
use nym_credential_storage::ephemeral_storage::EphemeralStorage as EphemeralCredentialStorage;
use nym_credential_storage::storage::Storage as CredentialStorage;
use nym_credentials::CredentialSpendingData;
use nym_credentials_interface::TicketType;
use nym_crypto::asymmetric::identity;
use nym_gateway_requests::registration::handshake::client_handshake;
use nym_gateway_requests::{
Expand Down Expand Up @@ -748,7 +749,11 @@ impl<C, St> GatewayClient<C, St> {
}
let prepared_credential = self
.unchecked_bandwidth_controller()
.prepare_ecash_ticket(self.gateway_identity.to_bytes(), TICKETS_TO_SPEND)
.prepare_ecash_ticket(
TicketType::V1MixnetEntry,
self.gateway_identity.to_bytes(),
TICKETS_TO_SPEND,
)
.await?;

match self.claim_ecash_bandwidth(prepared_credential.data).await {
Expand Down
7 changes: 6 additions & 1 deletion common/commands/src/ecash/generate_ticket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@ use comfy_table::Table;
use nym_credential_storage::initialise_persistent_storage;
use nym_credential_storage::storage::Storage;
use nym_credentials::ecash::bandwidth::serialiser::VersionedSerialise;
use nym_credentials_interface::TicketType;
use std::path::PathBuf;

#[derive(Debug, Parser)]
pub struct Args {
/// Specify which type of ticketbook
#[clap(long, default_value_t = TicketType::V1MixnetEntry)]
pub(crate) ticketbook_type: TicketType,

/// Specify the index of the ticket to retrieve from the ticketbook.
/// By default, the current unspent value is used.
#[clap(long, group = "output")]
Expand Down Expand Up @@ -62,7 +67,7 @@ pub async fn execute(args: Args) -> anyhow::Result<()> {

let persistent_storage = initialise_persistent_storage(&credentials_store).await;
let Some(mut next_ticketbook) = persistent_storage
.get_next_unspent_usable_ticketbook(0)
.get_next_unspent_usable_ticketbook(args.ticketbook_type.to_string(), 0)
.await?
else {
bail!(
Expand Down
2 changes: 1 addition & 1 deletion common/commands/src/ecash/issue_ticket_book.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ async fn issue_to_file(args: Args, client: SigningClient) -> anyhow::Result<()>
utils::issue_credential(&client, &credentials_store, &secret, args.ticketbook_type).await?;

let ticketbook = credentials_store
.get_next_unspent_usable_ticketbook(0)
.get_next_unspent_usable_ticketbook(args.ticketbook_type.to_string(), 0)
.await?
.ok_or(anyhow!("we just issued a ticketbook, it must be present!"))?
.ticketbook;
Expand Down
2 changes: 2 additions & 0 deletions common/credential-storage/src/backends/memory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ impl MemoryEcachTicketbookManager {

pub async fn get_next_unspent_ticketbook_and_update(
&self,
ticketbook_type: String,
tickets: u32,
) -> Option<RetrievedTicketbook> {
let mut guard = self.inner.write().await;
Expand All @@ -81,6 +82,7 @@ impl MemoryEcachTicketbookManager {
if !t.ticketbook.expired()
&& t.ticketbook.spent_tickets() + tickets as u64
<= t.ticketbook.params_total_tickets()
&& t.ticketbook.ticketbook_type().to_string() == ticketbook_type
{
t.ticketbook
.update_spent_tickets(t.ticketbook.spent_tickets() + tickets as u64);
Expand Down
3 changes: 3 additions & 0 deletions common/credential-storage/src/backends/sqlite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ impl SqliteEcashTicketbookManager {

pub(crate) async fn get_next_unspent_ticketbook<'a, E>(
executor: E,
ticketbook_type: String,
deadline: Date,
tickets: u32,
) -> Result<Option<StoredIssuedTicketbook>, sqlx::Error>
Expand All @@ -296,12 +297,14 @@ where
FROM ecash_ticketbook
WHERE used_tickets + ? <= total_tickets
AND expiration_date >= ?
AND ticketbook_type = ?
ORDER BY expiration_date ASC
LIMIT 1
"#,
)
.bind(tickets)
.bind(deadline)
.bind(ticketbook_type)
.fetch_optional(executor)
.await
}
Expand Down
5 changes: 3 additions & 2 deletions common/credential-storage/src/ephemeral_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,18 @@ impl Storage for EphemeralStorage {
Ok(())
}

/// Tries to retrieve one of the stored ticketbook,
/// Tries to retrieve one of the stored ticketbook for the specified type,
/// that has not yet expired and has required number of unspent tickets.
/// it immediately updated the on-disk number of used tickets so that another task
/// could obtain their own tickets at the same time
async fn get_next_unspent_usable_ticketbook(
&self,
ticketbook_type: String,
tickets: u32,
) -> Result<Option<RetrievedTicketbook>, Self::StorageError> {
Ok(self
.storage_manager
.get_next_unspent_ticketbook_and_update(tickets)
.get_next_unspent_ticketbook_and_update(ticketbook_type, tickets)
.await)
}

Expand Down
5 changes: 4 additions & 1 deletion common/credential-storage/src/persistent_storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,13 +171,16 @@ impl Storage for PersistentStorage {
/// could obtain their own tickets at the same time
async fn get_next_unspent_usable_ticketbook(
&self,
ticketbook_type: String,
tickets: u32,
) -> Result<Option<RetrievedTicketbook>, Self::StorageError> {
let deadline = ecash_today().ecash_date();
let mut tx = self.storage_manager.begin_storage_tx().await?;

// we don't want ticketbooks with expiration in the past
let Some(raw) = get_next_unspent_ticketbook(&mut tx, deadline, tickets).await? else {
let Some(raw) =
get_next_unspent_ticketbook(&mut tx, ticketbook_type, deadline, tickets).await?
else {
// make sure to finish our tx
tx.commit().await?;
return Ok(None);
Expand Down
3 changes: 2 additions & 1 deletion common/credential-storage/src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,13 @@ pub trait Storage: Send + Sync {

async fn remove_pending_ticketbook(&self, pending_id: i64) -> Result<(), Self::StorageError>;

/// Tries to retrieve one of the stored ticketbook,
/// Tries to retrieve one of the stored ticketbook for the specified type,
/// that has not yet expired and has required number of unspent tickets.
/// it immediately updated the on-disk number of used tickets so that another task
/// could obtain their own tickets at the same time
async fn get_next_unspent_usable_ticketbook(
&self,
ticketbook_type: String,
tickets: u32,
) -> Result<Option<RetrievedTicketbook>, Self::StorageError>;

Expand Down

0 comments on commit 8758bea

Please sign in to comment.