|
@@ -219,6 +219,24 @@ where
|
|
|
.execute(&self.inner)
|
|
.execute(&self.inner)
|
|
|
.await?;
|
|
.await?;
|
|
|
|
|
|
|
|
|
|
+ if new_state == State::Spent {
|
|
|
|
|
+ // Update keyset_amounts table for redeemed amounts
|
|
|
|
|
+ query(
|
|
|
|
|
+ r#"
|
|
|
|
|
+ INSERT INTO keyset_amounts (keyset_id, type, amount)
|
|
|
|
|
+ SELECT keyset_id, 'redeemed', COALESCE(SUM(amount), 0)
|
|
|
|
|
+ FROM proof
|
|
|
|
|
+ WHERE y IN (:ys)
|
|
|
|
|
+ GROUP BY keyset_id
|
|
|
|
|
+ ON CONFLICT (keyset_id, type)
|
|
|
|
|
+ DO UPDATE SET amount = keyset_amounts.amount + EXCLUDED.amount
|
|
|
|
|
+ "#,
|
|
|
|
|
+ )?
|
|
|
|
|
+ .bind_vec("ys", ys.iter().map(|y| y.to_bytes().to_vec()).collect())
|
|
|
|
|
+ .execute(&self.inner)
|
|
|
|
|
+ .await?;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
Ok(ys.iter().map(|y| current_states.remove(y)).collect())
|
|
Ok(ys.iter().map(|y| current_states.remove(y)).collect())
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1618,6 +1636,26 @@ where
|
|
|
.into_iter()
|
|
.into_iter()
|
|
|
.unzip())
|
|
.unzip())
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /// Get total proofs redeemed by keyset id
|
|
|
|
|
+ async fn get_total_redeemed(&self) -> Result<HashMap<Id, Amount>, Self::Err> {
|
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
|
|
|
+ query(
|
|
|
|
|
+ r#"
|
|
|
|
|
+ SELECT
|
|
|
|
|
+ keyset_id,
|
|
|
|
|
+ amount
|
|
|
|
|
+ FROM
|
|
|
|
|
+ keyset_amounts
|
|
|
|
|
+ WHERE type = 'redeemed'
|
|
|
|
|
+ "#,
|
|
|
|
|
+ )?
|
|
|
|
|
+ .fetch_all(&*conn)
|
|
|
|
|
+ .await?
|
|
|
|
|
+ .into_iter()
|
|
|
|
|
+ .map(sql_row_to_hashmap_amount)
|
|
|
|
|
+ .collect()
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[async_trait]
|
|
#[async_trait]
|
|
@@ -1698,6 +1736,19 @@ where
|
|
|
.bind("signed_time", current_time as i64)
|
|
.bind("signed_time", current_time as i64)
|
|
|
.execute(&self.inner)
|
|
.execute(&self.inner)
|
|
|
.await?;
|
|
.await?;
|
|
|
|
|
+
|
|
|
|
|
+ query(
|
|
|
|
|
+ r#"
|
|
|
|
|
+ INSERT INTO keyset_amounts (keyset_id, type, amount)
|
|
|
|
|
+ VALUES (:keyset_id, 'issued', :amount)
|
|
|
|
|
+ ON CONFLICT (keyset_id, type)
|
|
|
|
|
+ DO UPDATE SET amount = keyset_amounts.amount + :amount
|
|
|
|
|
+ "#,
|
|
|
|
|
+ )?
|
|
|
|
|
+ .bind("amount", u64::from(signature.amount) as i64)
|
|
|
|
|
+ .bind("keyset_id", signature.keyset_id.to_string())
|
|
|
|
|
+ .execute(&self.inner)
|
|
|
|
|
+ .await?;
|
|
|
}
|
|
}
|
|
|
Some((c, _dleq_e, _dleq_s)) => {
|
|
Some((c, _dleq_e, _dleq_s)) => {
|
|
|
// Blind message exists: check if c is NULL
|
|
// Blind message exists: check if c is NULL
|
|
@@ -1725,6 +1776,19 @@ where
|
|
|
.bind("amount", u64::from(signature.amount) as i64)
|
|
.bind("amount", u64::from(signature.amount) as i64)
|
|
|
.execute(&self.inner)
|
|
.execute(&self.inner)
|
|
|
.await?;
|
|
.await?;
|
|
|
|
|
+
|
|
|
|
|
+ query(
|
|
|
|
|
+ r#"
|
|
|
|
|
+ INSERT INTO keyset_amounts (keyset_id, type, amount)
|
|
|
|
|
+ VALUES (:keyset_id, 'issued', :amount)
|
|
|
|
|
+ ON CONFLICT (keyset_id, type)
|
|
|
|
|
+ DO UPDATE SET amount = keyset_amounts.amount + :amount
|
|
|
|
|
+ "#,
|
|
|
|
|
+ )?
|
|
|
|
|
+ .bind("amount", u64::from(signature.amount) as i64)
|
|
|
|
|
+ .bind("keyset_id", signature.keyset_id.to_string())
|
|
|
|
|
+ .execute(&self.inner)
|
|
|
|
|
+ .await?;
|
|
|
}
|
|
}
|
|
|
_ => {
|
|
_ => {
|
|
|
// Blind message already has c: Error
|
|
// Blind message already has c: Error
|
|
@@ -1907,6 +1971,26 @@ where
|
|
|
.map(sql_row_to_blind_signature)
|
|
.map(sql_row_to_blind_signature)
|
|
|
.collect::<Result<Vec<BlindSignature>, _>>()?)
|
|
.collect::<Result<Vec<BlindSignature>, _>>()?)
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ /// Get total proofs redeemed by keyset id
|
|
|
|
|
+ async fn get_total_issued(&self) -> Result<HashMap<Id, Amount>, Self::Err> {
|
|
|
|
|
+ let conn = self.pool.get().map_err(|e| Error::Database(Box::new(e)))?;
|
|
|
|
|
+ query(
|
|
|
|
|
+ r#"
|
|
|
|
|
+ SELECT
|
|
|
|
|
+ keyset_id,
|
|
|
|
|
+ amount
|
|
|
|
|
+ FROM
|
|
|
|
|
+ keyset_amounts
|
|
|
|
|
+ WHERE type = 'issued'
|
|
|
|
|
+ "#,
|
|
|
|
|
+ )?
|
|
|
|
|
+ .fetch_all(&*conn)
|
|
|
|
|
+ .await?
|
|
|
|
|
+ .into_iter()
|
|
|
|
|
+ .map(sql_row_to_hashmap_amount)
|
|
|
|
|
+ .collect()
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
#[async_trait]
|
|
#[async_trait]
|
|
@@ -2482,6 +2566,20 @@ fn sql_row_to_proof(row: Vec<Column>) -> Result<Proof, Error> {
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+fn sql_row_to_hashmap_amount(row: Vec<Column>) -> Result<(Id, Amount), Error> {
|
|
|
|
|
+ unpack_into!(
|
|
|
|
|
+ let (
|
|
|
|
|
+ keyset_id, amount
|
|
|
|
|
+ ) = row
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ let amount: u64 = column_as_number!(amount);
|
|
|
|
|
+ Ok((
|
|
|
|
|
+ column_as_string!(keyset_id, Id::from_str, Id::from_bytes),
|
|
|
|
|
+ Amount::from(amount),
|
|
|
|
|
+ ))
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
fn sql_row_to_proof_with_state(row: Vec<Column>) -> Result<(Proof, Option<State>), Error> {
|
|
fn sql_row_to_proof_with_state(row: Vec<Column>) -> Result<(Proof, Option<State>), Error> {
|
|
|
unpack_into!(
|
|
unpack_into!(
|
|
|
let (
|
|
let (
|