storage implementation
This commit is contained in:
@@ -3,8 +3,10 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
CREATE TABLE ISSUED_FREEPASS
|
||||
CREATE TABLE issued_freepass
|
||||
(
|
||||
id INTEGER PRIMARY KEY CHECK (id = 0),
|
||||
current_nonce INTEGER NOT NULL
|
||||
);
|
||||
);
|
||||
|
||||
INSERT INTO issued_freepass(id, current_nonce) VALUES (0,0);
|
||||
@@ -149,7 +149,7 @@ pub struct FreePassRequest {
|
||||
|
||||
// we need to include a nonce here to prevent replay attacks
|
||||
// (and not making the nym-api store the serial numbers of all issued credential)
|
||||
pub used_nonce: u64,
|
||||
pub used_nonce: u32,
|
||||
|
||||
/// Signature on the nonce
|
||||
/// to prove the possession of the cosmos key/address
|
||||
@@ -163,7 +163,7 @@ impl FreePassRequest {
|
||||
self.cosmos_pubkey.into()
|
||||
}
|
||||
|
||||
pub fn nonce_plaintext(&self) -> [u8; 8] {
|
||||
pub fn nonce_plaintext(&self) -> [u8; 4] {
|
||||
self.used_nonce.to_be_bytes()
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ pub enum CoconutError {
|
||||
FreePassSignatureVerificationFailure,
|
||||
|
||||
#[error("the provided signing nonce is invalid. the current value is: {current}. got {received} instead")]
|
||||
InvalidNonce { current: u64, received: u64 },
|
||||
InvalidNonce { current: u32, received: u32 },
|
||||
|
||||
#[error("only secp256k1 keys are supported for free pass issuance")]
|
||||
UnsupportedNonSecp256k1Key,
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
use crate::coconut::storage::models::{EpochCredentials, IssuedCredential};
|
||||
use crate::support::storage::manager::StorageManager;
|
||||
use nym_coconut_dkg_common::types::EpochId;
|
||||
use thiserror::Error;
|
||||
|
||||
#[async_trait]
|
||||
pub trait CoconutStorageManagerExt {
|
||||
@@ -120,6 +121,17 @@ pub trait CoconutStorageManagerExt {
|
||||
start_after: i64,
|
||||
limit: u32,
|
||||
) -> Result<Vec<IssuedCredential>, sqlx::Error>;
|
||||
|
||||
/// Attempts to retrieve the current value of the freepass nonce.
|
||||
async fn get_current_freepass_nonce(&self) -> Result<u32, sqlx::Error>;
|
||||
|
||||
/// Attempt to update the currently stored nonce to the provided value whilst ensuring
|
||||
/// it's strictly equal the current value plus 1
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `new`: the new value of the free pass nonce
|
||||
async fn update_and_validate_freepass_nonce(&self, new: u32) -> Result<(), sqlx::Error>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
@@ -378,4 +390,49 @@ impl CoconutStorageManagerExt for StorageManager {
|
||||
.fetch_all(&self.connection_pool)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Attempts to retrieve the current value of the freepass nonce.
|
||||
async fn get_current_freepass_nonce(&self) -> Result<u32, sqlx::Error> {
|
||||
sqlx::query!("SELECT current_nonce as 'current_nonce: u32' FROM issued_freepass")
|
||||
.fetch_one(&self.connection_pool)
|
||||
.await
|
||||
.map(|row| row.current_nonce)
|
||||
}
|
||||
|
||||
/// Attempt to update the currently stored nonce to the provided value whilst ensuring
|
||||
/// it's strictly equal the current value plus 1
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `new`: the new value of the free pass nonce
|
||||
async fn update_and_validate_freepass_nonce(&self, new: u32) -> Result<(), sqlx::Error> {
|
||||
let mut tx = self.connection_pool.begin().await?;
|
||||
|
||||
let currently_stored =
|
||||
sqlx::query!("SELECT current_nonce as 'current_nonce: u32' FROM issued_freepass")
|
||||
.fetch_one(&mut tx)
|
||||
.await?
|
||||
.current_nonce;
|
||||
|
||||
if currently_stored + 1 != new {
|
||||
// this is not the best error but I really don't want to be creating a new enum
|
||||
return Err(sqlx::Error::Decode(Box::new(UnexpectedNonce {
|
||||
current: currently_stored,
|
||||
got: new,
|
||||
})));
|
||||
}
|
||||
|
||||
sqlx::query!("UPDATE issued_freepass SET current_nonce = ?", new)
|
||||
.execute(&mut tx)
|
||||
.await?;
|
||||
|
||||
tx.commit().await
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
#[error("tried to store an invalid nonce. the received value is {got} while current is {current}. expected {current} + 1")]
|
||||
pub struct UnexpectedNonce {
|
||||
current: u32,
|
||||
got: u32,
|
||||
}
|
||||
|
||||
@@ -64,9 +64,9 @@ pub trait CoconutStorageExt {
|
||||
pagination: Pagination<i64>,
|
||||
) -> Result<Vec<IssuedCredential>, NymApiStorageError>;
|
||||
|
||||
async fn get_current_freepass_nonce(&self) -> Result<u64, NymApiStorageError>;
|
||||
async fn get_current_freepass_nonce(&self) -> Result<u32, NymApiStorageError>;
|
||||
|
||||
async fn update_and_validate_freepass_nonce(&self, new: u64) -> Result<(), NymApiStorageError>;
|
||||
async fn update_and_validate_freepass_nonce(&self, new: u32) -> Result<(), NymApiStorageError>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
@@ -168,11 +168,11 @@ impl CoconutStorageExt for NymApiStorage {
|
||||
.await?)
|
||||
}
|
||||
|
||||
async fn get_current_freepass_nonce(&self) -> Result<u64, NymApiStorageError> {
|
||||
async fn get_current_freepass_nonce(&self) -> Result<u32, NymApiStorageError> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
async fn update_and_validate_freepass_nonce(&self, new: u64) -> Result<(), NymApiStorageError> {
|
||||
async fn update_and_validate_freepass_nonce(&self, new: u32) -> Result<(), NymApiStorageError> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user