bugfix: make sure to update timestamp of last batch verification to prevent double redemption (#5239)

This commit is contained in:
Jędrzej Stuczyński
2024-12-10 13:35:29 +00:00
committed by GitHub
parent c29fce0856
commit 66fea38d20
5 changed files with 72 additions and 18 deletions
Generated
+1 -1
View File
@@ -6058,7 +6058,7 @@ dependencies = [
[[package]]
name = "nym-node-status-api"
version = "1.0.0-rc.6"
version = "1.0.0-rc.7"
dependencies = [
"anyhow",
"axum 0.7.7",
+7 -1
View File
@@ -203,7 +203,7 @@ async fn batch_redeem_tickets(
// 5. check if **every** serial number included in the request has been verified by us
// if we have more than requested, tough luck, they're going to lose them
let verified = state.get_redeemable_tickets(provider_info).await?;
let verified = state.get_redeemable_tickets(&provider_info).await?;
let verified_tickets: HashSet<_> = verified.iter().map(|sn| sn.deref()).collect();
for sn in &received {
@@ -215,8 +215,14 @@ async fn batch_redeem_tickets(
}
}
// 6. vote on the proposal
// TODO: offload it to separate task with work queue and batching (of tx messages) to vote for multiple proposals in the same tx
// similarly to what we do inside the credential proxy
state.accept_proposal(proposal_id).await?;
// 7. update the time of the last verification for this provider
state.update_last_batch_verification(&provider_info).await?;
Ok(Json(EcashBatchTicketRedemptionResponse {
proposal_accepted: true,
}))
+9 -1
View File
@@ -890,7 +890,7 @@ impl EcashState {
pub async fn get_redeemable_tickets(
&self,
provider_info: TicketProvider,
provider_info: &TicketProvider,
) -> Result<Vec<SerialNumberWrapper>> {
let since = provider_info
.last_batch_verification
@@ -903,6 +903,14 @@ impl EcashState {
.map_err(Into::into)
}
pub async fn update_last_batch_verification(&self, provider: &TicketProvider) -> Result<()> {
Ok(self
.aux
.storage
.update_last_batch_verification(provider.id, OffsetDateTime::now_utc())
.await?)
}
pub async fn get_ticket_data_by_serial_number(
&self,
serial_number: &[u8],
+39 -15
View File
@@ -82,6 +82,11 @@ pub trait EcashStorageManagerExt {
provider_id: i64,
since: OffsetDateTime,
) -> Result<Vec<SerialNumberWrapper>, sqlx::Error>;
async fn update_last_batch_verification(
&self,
provider_id: i64,
last_batch_verification: OffsetDateTime,
) -> Result<(), sqlx::Error>;
async fn get_spent_tickets_on(
&self,
@@ -215,15 +220,15 @@ impl EcashStorageManagerExt for StorageManager {
"#,
expiration_date
)
.fetch_all(&self.connection_pool)
.await?
.into_iter()
.filter_map(|r| r.merkle_leaf.try_into().inspect_err(|_| error!("possible database corruption: one of the stored merkle leaves is not a valid 32byte hash")).ok().map(|merkle_leaf| IssuedHash {
deposit_id: r.deposit_id,
merkle_leaf,
merkle_index: r.merkle_index as usize,
}))
.collect())
.fetch_all(&self.connection_pool)
.await?
.into_iter()
.filter_map(|r| r.merkle_leaf.try_into().inspect_err(|_| error!("possible database corruption: one of the stored merkle leaves is not a valid 32byte hash")).ok().map(|merkle_leaf| IssuedHash {
deposit_id: r.deposit_id,
merkle_leaf,
merkle_index: r.merkle_index as usize,
}))
.collect())
}
/// Store the provided issued credential information.
@@ -344,8 +349,8 @@ impl EcashStorageManagerExt for StorageManager {
verified_at,
provider_id
)
.execute(&self.connection_pool)
.await?;
.execute(&self.connection_pool)
.await?;
Ok(())
}
@@ -382,6 +387,25 @@ impl EcashStorageManagerExt for StorageManager {
.await
}
async fn update_last_batch_verification(
&self,
provider_id: i64,
last_batch_verification: OffsetDateTime,
) -> Result<(), sqlx::Error> {
sqlx::query!(
r#"
UPDATE ticket_providers
SET last_batch_verification = ?
WHERE id = ?
"#,
last_batch_verification,
provider_id
)
.execute(&self.connection_pool)
.await?;
Ok(())
}
async fn get_spent_tickets_on(
&self,
date: Date,
@@ -510,8 +534,8 @@ impl EcashStorageManagerExt for StorageManager {
epoch_id,
data
)
.execute(&self.connection_pool)
.await?;
.execute(&self.connection_pool)
.await?;
Ok(())
}
@@ -544,8 +568,8 @@ impl EcashStorageManagerExt for StorageManager {
epoch_id,
data
)
.execute(&self.connection_pool)
.await?;
.execute(&self.connection_pool)
.await?;
Ok(())
}
+16
View File
@@ -112,6 +112,11 @@ pub trait EcashStorageExt {
provider_id: i64,
since: OffsetDateTime,
) -> Result<Vec<SerialNumberWrapper>, NymApiStorageError>;
async fn update_last_batch_verification(
&self,
provider_id: i64,
last_batch_verification: OffsetDateTime,
) -> Result<(), NymApiStorageError>;
async fn get_all_spent_tickets_on(
&self,
@@ -395,6 +400,17 @@ impl EcashStorageExt for NymApiStorage {
.map_err(Into::into)
}
async fn update_last_batch_verification(
&self,
provider_id: i64,
last_batch_verification: OffsetDateTime,
) -> Result<(), NymApiStorageError> {
Ok(self
.manager
.update_last_batch_verification(provider_id, last_batch_verification)
.await?)
}
async fn get_all_spent_tickets_on(
&self,
date: Date,