spent credential storage on validators

This commit is contained in:
Simon Wicky
2024-05-07 13:34:11 +02:00
parent 24358176fd
commit d57ff735df
5 changed files with 153 additions and 3 deletions
@@ -0,0 +1,14 @@
/*
* Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
* SPDX-License-Identifier: Apache-2.0
*/
create table spent_credentials
(
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
credential TEXT NOT NULL,
serial_number TEXT NOT NULL,
gateway_address TEXT NOT NULL,
proposal_id TEXT NOT NULL
);
+28
View File
@@ -169,6 +169,34 @@ impl State {
.aggregated_verification_key(epoch_id)
.await
}
pub async fn store_credential(
&self,
credential: &CredentialSpendingData,
gateway_addr: &AccountId,
proposal_id: u64,
) -> Result<()> {
self.storage
.insert_credential(
credential,
credential.serial_number_b58(),
gateway_addr,
proposal_id,
)
.await
.map_err(|err| err.into())
}
pub async fn get_credential_by_sn(
&self,
serial_number_bs58: String,
) -> Result<Option<CredentialSpendingData>> {
self.storage
.get_credential(serial_number_bs58)
.await
.map_err(|err| err.into())
}
pub async fn get_coin_indices_signatures(&self) -> Result<Vec<CoinIndexSignature>> {
let current_epoch = self.client.get_current_epoch().await?;
match self
+58 -1
View File
@@ -1,7 +1,7 @@
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: GPL-3.0-only
use crate::coconut::storage::models::{EpochCredentials, IssuedCredential};
use crate::coconut::storage::models::{EpochCredentials, IssuedCredential, SpentCredential};
use crate::support::storage::manager::StorageManager;
use nym_coconut_dkg_common::types::EpochId;
use thiserror::Error;
@@ -94,6 +94,25 @@ pub trait CoconutStorageManagerExt {
limit: u32,
) -> Result<Vec<IssuedCredential>, sqlx::Error>;
/// Creates new credential entry for a given gateway addr.
///
/// # Arguments
///
/// * `credential`: base58 repr of a credential.
/// * `gateway_addr`: cosmos address of the gateway
async fn insert_credential(
&self,
credential: String,
serial_number: String,
gateway_addr: String,
proposal_id: String,
) -> Result<(), sqlx::Error>;
async fn get_credential(
&self,
serial_number: String,
) -> Result<Option<SpentCredential>, sqlx::Error>;
async fn increment_issued_freepasses(&self) -> Result<(), sqlx::Error>;
}
@@ -354,6 +373,44 @@ impl CoconutStorageManagerExt for StorageManager {
.await
}
/// Creates new credential entry for a given gateway addr.
///
/// # Arguments
///
/// * `credential`: base58 repr of a credential.
/// * `gateway_addr`: cosmos address of the gateway
async fn insert_credential(
&self,
credential: String,
serial_number: String,
gateway_addr: String,
proposal_id: String,
) -> Result<(), sqlx::Error> {
sqlx::query!(
"INSERT INTO spent_credentials(credential, serial_number, gateway_address, proposal_id) VALUES (?, ?, ?, ?)",
credential,
serial_number,
gateway_addr,
proposal_id,
)
.execute(&self.connection_pool)
.await?;
Ok(())
}
async fn get_credential(
&self,
serial_number: String,
) -> Result<Option<SpentCredential>, sqlx::Error> {
sqlx::query_as!(
SpentCredential,
"SELECT credential from spent_credentials where serial_number = ?",
serial_number,
)
.fetch_optional(&self.connection_pool)
.await
}
async fn increment_issued_freepasses(&self) -> Result<(), sqlx::Error> {
sqlx::query!("UPDATE issued_freepass SET issued = issued + 1",)
.execute(&self.connection_pool)
+49 -2
View File
@@ -6,12 +6,12 @@ use crate::coconut::storage::models::{join_attributes, EpochCredentials, IssuedC
use crate::node_status_api::models::NymApiStorageError;
use crate::support::storage::NymApiStorage;
use nym_api_requests::coconut::models::Pagination;
use nym_coconut::{Base58, BlindedSignature};
use nym_coconut_dkg_common::types::EpochId;
use nym_compact_ecash::utils::BlindedSignature;
use nym_compact_ecash::Base58;
use nym_credentials::CredentialSpendingData;
use nym_crypto::asymmetric::identity;
use nym_validator_client::nyxd::Hash;
use nym_validator_client::nyxd::{AccountId, Hash};
pub(crate) mod manager;
pub(crate) mod models;
@@ -67,6 +67,19 @@ pub trait CoconutStorageExt {
pagination: Pagination<i64>,
) -> Result<Vec<IssuedCredential>, NymApiStorageError>;
async fn insert_credential(
&self,
credential: &CredentialSpendingData,
serial_number_bs58: String,
gateway_addr: &AccountId,
proposal_id: u64,
) -> Result<(), NymApiStorageError>;
async fn get_credential(
&self,
serial_number_bs58: String,
) -> Result<Option<CredentialSpendingData>, NymApiStorageError>;
async fn increment_issued_freepasses(&self) -> Result<(), NymApiStorageError>;
}
@@ -169,6 +182,40 @@ impl CoconutStorageExt for NymApiStorage {
.await?)
}
async fn insert_credential(
&self,
credential: &CredentialSpendingData,
serial_number_bs58: String,
gateway_addr: &AccountId,
proposal_id: u64,
) -> Result<(), NymApiStorageError> {
self.manager
.insert_credential(
credential.to_bs58(),
serial_number_bs58,
gateway_addr.to_string(),
proposal_id.to_string(),
)
.await
.map_err(|err| err.into())
}
async fn get_credential(
&self,
serial_number_bs58: String,
) -> Result<Option<CredentialSpendingData>, NymApiStorageError> {
let credential = self.manager.get_credential(serial_number_bs58).await?;
credential
.map(|cred| {
CredentialSpendingData::try_from_bs58(cred.credential).map_err(|_| {
NymApiStorageError::DatabaseInconsistency {
reason: "impossible to deserialize credential".to_string(),
}
})
})
.transpose()
}
async fn increment_issued_freepasses(&self) -> Result<(), NymApiStorageError> {
Ok(self.manager.increment_issued_freepasses().await?)
}
+4
View File
@@ -33,6 +33,10 @@ impl From<EpochCredentials> for EpochCredentialsResponse {
}
}
pub struct SpentCredential {
pub credential: String,
}
#[derive(FromRow)]
pub struct IssuedCredential {
pub id: i64,