storage implementation

This commit is contained in:
Jędrzej Stuczyński
2024-02-09 17:23:58 +00:00
parent c9ff550311
commit f61b898c4f
5 changed files with 68 additions and 9 deletions
@@ -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()
}
+1 -1
View File
@@ -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,
+57
View File
@@ -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,
}
+4 -4
View File
@@ -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!()
}
}