spent credential storage on validators
This commit is contained in:
@@ -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
|
||||
|
||||
);
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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?)
|
||||
}
|
||||
|
||||
@@ -33,6 +33,10 @@ impl From<EpochCredentials> for EpochCredentialsResponse {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SpentCredential {
|
||||
pub credential: String,
|
||||
}
|
||||
|
||||
#[derive(FromRow)]
|
||||
pub struct IssuedCredential {
|
||||
pub id: i64,
|
||||
|
||||
Reference in New Issue
Block a user