mirror of
https://github.com/aljazceru/cdk.git
synced 2025-12-23 23:55:01 +01:00
refactor: get spent and pending proofs by list of secrets or ys
This commit is contained in:
@@ -518,34 +518,56 @@ impl MintDatabase for MintRedbDatabase {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_spent_proof_by_y(&self, y: &PublicKey) -> Result<Option<Proof>, Self::Err> {
|
async fn get_spent_proofs_by_ys(
|
||||||
|
&self,
|
||||||
|
ys: &[PublicKey],
|
||||||
|
) -> Result<Vec<Option<Proof>>, Self::Err> {
|
||||||
let db = self.db.lock().await;
|
let db = self.db.lock().await;
|
||||||
let read_txn = db.begin_read().map_err(Error::from)?;
|
let read_txn = db.begin_read().map_err(Error::from)?;
|
||||||
let table = read_txn
|
let table = read_txn
|
||||||
.open_table(SPENT_PROOFS_TABLE)
|
.open_table(SPENT_PROOFS_TABLE)
|
||||||
.map_err(Error::from)?;
|
.map_err(Error::from)?;
|
||||||
|
|
||||||
|
let mut proofs = Vec::with_capacity(ys.len());
|
||||||
|
|
||||||
|
for y in ys {
|
||||||
match table.get(y.to_bytes()).map_err(Error::from)? {
|
match table.get(y.to_bytes()).map_err(Error::from)? {
|
||||||
Some(proof) => Ok(serde_json::from_str(proof.value()).map_err(Error::from)?),
|
Some(proof) => proofs.push(Some(
|
||||||
None => Ok(None),
|
serde_json::from_str(proof.value()).map_err(Error::from)?,
|
||||||
|
)),
|
||||||
|
None => proofs.push(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_spent_proof_by_secret(&self, secret: &Secret) -> Result<Option<Proof>, Self::Err> {
|
Ok(proofs)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_spent_proofs_by_secrets(
|
||||||
|
&self,
|
||||||
|
secrets: &[Secret],
|
||||||
|
) -> Result<Vec<Option<Proof>>, Self::Err> {
|
||||||
let db = self.db.lock().await;
|
let db = self.db.lock().await;
|
||||||
let read_txn = db.begin_read().map_err(Error::from)?;
|
let read_txn = db.begin_read().map_err(Error::from)?;
|
||||||
let table = read_txn
|
let table = read_txn
|
||||||
.open_table(SPENT_PROOFS_TABLE)
|
.open_table(SPENT_PROOFS_TABLE)
|
||||||
.map_err(Error::from)?;
|
.map_err(Error::from)?;
|
||||||
|
|
||||||
|
let mut proofs = Vec::with_capacity(secrets.len());
|
||||||
|
|
||||||
|
for secret in secrets {
|
||||||
let y: PublicKey = hash_to_curve(&secret.to_bytes())?;
|
let y: PublicKey = hash_to_curve(&secret.to_bytes())?;
|
||||||
|
|
||||||
match table.get(y.to_bytes()).map_err(Error::from)? {
|
match table.get(y.to_bytes()).map_err(Error::from)? {
|
||||||
Some(proof) => Ok(serde_json::from_str(proof.value()).map_err(Error::from)?),
|
Some(proof) => proofs.push(Some(
|
||||||
None => Ok(None),
|
serde_json::from_str(proof.value()).map_err(Error::from)?,
|
||||||
|
)),
|
||||||
|
None => proofs.push(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(proofs)
|
||||||
|
}
|
||||||
|
|
||||||
async fn add_pending_proofs(&self, proofs: Vec<Proof>) -> Result<(), Self::Err> {
|
async fn add_pending_proofs(&self, proofs: Vec<Proof>) -> Result<(), Self::Err> {
|
||||||
let db = self.db.lock().await;
|
let db = self.db.lock().await;
|
||||||
|
|
||||||
@@ -569,35 +591,54 @@ impl MintDatabase for MintRedbDatabase {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_pending_proof_by_y(&self, y: &PublicKey) -> Result<Option<Proof>, Self::Err> {
|
async fn get_pending_proofs_by_ys(
|
||||||
|
&self,
|
||||||
|
ys: &[PublicKey],
|
||||||
|
) -> Result<Vec<Option<Proof>>, Self::Err> {
|
||||||
let db = self.db.lock().await;
|
let db = self.db.lock().await;
|
||||||
let read_txn = db.begin_read().map_err(Error::from)?;
|
let read_txn = db.begin_read().map_err(Error::from)?;
|
||||||
let table = read_txn
|
let table = read_txn
|
||||||
.open_table(PENDING_PROOFS_TABLE)
|
.open_table(PENDING_PROOFS_TABLE)
|
||||||
.map_err(Error::from)?;
|
.map_err(Error::from)?;
|
||||||
|
|
||||||
|
let mut proofs = Vec::with_capacity(ys.len());
|
||||||
|
|
||||||
|
for y in ys {
|
||||||
|
match table.get(y.to_bytes()).map_err(Error::from)? {
|
||||||
|
Some(proof) => proofs.push(Some(
|
||||||
|
serde_json::from_str(proof.value()).map_err(Error::from)?,
|
||||||
|
)),
|
||||||
|
None => proofs.push(None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(proofs)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_pending_proofs_by_secrets(
|
||||||
|
&self,
|
||||||
|
secrets: &[Secret],
|
||||||
|
) -> Result<Vec<Option<Proof>>, Self::Err> {
|
||||||
|
let db = self.db.lock().await;
|
||||||
|
let read_txn = db.begin_read().map_err(Error::from)?;
|
||||||
|
let table = read_txn
|
||||||
|
.open_table(PENDING_PROOFS_TABLE)
|
||||||
|
.map_err(Error::from)?;
|
||||||
|
|
||||||
|
let mut proofs = Vec::with_capacity(secrets.len());
|
||||||
|
|
||||||
|
for secret in secrets {
|
||||||
|
let y: PublicKey = hash_to_curve(&secret.to_bytes())?;
|
||||||
|
|
||||||
match table.get(y.to_bytes()).map_err(Error::from)? {
|
match table.get(y.to_bytes()).map_err(Error::from)? {
|
||||||
Some(proof) => Ok(serde_json::from_str(proof.value()).map_err(Error::from)?),
|
Some(proof) => proofs.push(Some(
|
||||||
None => Ok(None),
|
serde_json::from_str(proof.value()).map_err(Error::from)?,
|
||||||
|
)),
|
||||||
|
None => proofs.push(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_pending_proof_by_secret(
|
Ok(proofs)
|
||||||
&self,
|
|
||||||
secret: &Secret,
|
|
||||||
) -> Result<Option<Proof>, Self::Err> {
|
|
||||||
let db = self.db.lock().await;
|
|
||||||
let read_txn = db.begin_read().map_err(Error::from)?;
|
|
||||||
let table = read_txn
|
|
||||||
.open_table(PENDING_PROOFS_TABLE)
|
|
||||||
.map_err(Error::from)?;
|
|
||||||
|
|
||||||
let secret_hash = hash_to_curve(&secret.to_bytes())?;
|
|
||||||
|
|
||||||
match table.get(secret_hash.to_bytes()).map_err(Error::from)? {
|
|
||||||
Some(proof) => Ok(serde_json::from_str(proof.value()).map_err(Error::from)?),
|
|
||||||
None => Ok(None),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn remove_pending_proofs(&self, secrets: Vec<&Secret>) -> Result<(), Self::Err> {
|
async fn remove_pending_proofs(&self, secrets: Vec<&Secret>) -> Result<(), Self::Err> {
|
||||||
|
|||||||
@@ -506,7 +506,15 @@ VALUES (?, ?, ?, ?, ?, ?, ?);
|
|||||||
transaction.commit().await.map_err(Error::from)?;
|
transaction.commit().await.map_err(Error::from)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
async fn get_spent_proof_by_secret(&self, secret: &Secret) -> Result<Option<Proof>, Self::Err> {
|
async fn get_spent_proofs_by_secrets(
|
||||||
|
&self,
|
||||||
|
secrets: &[Secret],
|
||||||
|
) -> Result<Vec<Option<Proof>>, Self::Err> {
|
||||||
|
let mut transaction = self.pool.begin().await.map_err(Error::from)?;
|
||||||
|
|
||||||
|
let mut proofs = Vec::with_capacity(secrets.len());
|
||||||
|
|
||||||
|
for secret in secrets {
|
||||||
let rec = sqlx::query(
|
let rec = sqlx::query(
|
||||||
r#"
|
r#"
|
||||||
SELECT *
|
SELECT *
|
||||||
@@ -516,20 +524,31 @@ AND state="SPENT";
|
|||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.bind(secret.to_string())
|
.bind(secret.to_string())
|
||||||
.fetch_one(&self.pool)
|
.fetch_one(&mut transaction)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let rec = match rec {
|
match rec {
|
||||||
Ok(rec) => rec,
|
Ok(rec) => {
|
||||||
|
proofs.push(Some(sqlite_row_to_proof(rec)?));
|
||||||
|
}
|
||||||
Err(err) => match err {
|
Err(err) => match err {
|
||||||
sqlx::Error::RowNotFound => return Ok(None),
|
sqlx::Error::RowNotFound => proofs.push(None),
|
||||||
_ => return Err(Error::SQLX(err).into()),
|
_ => return Err(Error::SQLX(err).into()),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Some(sqlite_row_to_proof(rec)?))
|
|
||||||
}
|
}
|
||||||
async fn get_spent_proof_by_y(&self, y: &PublicKey) -> Result<Option<Proof>, Self::Err> {
|
transaction.commit().await.map_err(Error::from)?;
|
||||||
|
|
||||||
|
Ok(proofs)
|
||||||
|
}
|
||||||
|
async fn get_spent_proofs_by_ys(
|
||||||
|
&self,
|
||||||
|
ys: &[PublicKey],
|
||||||
|
) -> Result<Vec<Option<Proof>>, Self::Err> {
|
||||||
|
let mut transaction = self.pool.begin().await.map_err(Error::from)?;
|
||||||
|
|
||||||
|
let mut proofs = Vec::with_capacity(ys.len());
|
||||||
|
for y in ys {
|
||||||
let rec = sqlx::query(
|
let rec = sqlx::query(
|
||||||
r#"
|
r#"
|
||||||
SELECT *
|
SELECT *
|
||||||
@@ -539,18 +558,23 @@ AND state="SPENT";
|
|||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.bind(y.to_bytes().to_vec())
|
.bind(y.to_bytes().to_vec())
|
||||||
.fetch_one(&self.pool)
|
.fetch_one(&mut transaction)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let rec = match rec {
|
match rec {
|
||||||
Ok(rec) => rec,
|
Ok(rec) => {
|
||||||
|
proofs.push(Some(sqlite_row_to_proof(rec)?));
|
||||||
|
}
|
||||||
Err(err) => match err {
|
Err(err) => match err {
|
||||||
sqlx::Error::RowNotFound => return Ok(None),
|
sqlx::Error::RowNotFound => proofs.push(None),
|
||||||
_ => return Err(Error::SQLX(err).into()),
|
_ => return Err(Error::SQLX(err).into()),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
Ok(Some(sqlite_row_to_proof(rec)?))
|
transaction.commit().await.map_err(Error::from)?;
|
||||||
|
|
||||||
|
Ok(proofs)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn add_pending_proofs(&self, proofs: Proofs) -> Result<(), Self::Err> {
|
async fn add_pending_proofs(&self, proofs: Proofs) -> Result<(), Self::Err> {
|
||||||
@@ -578,10 +602,15 @@ VALUES (?, ?, ?, ?, ?, ?, ?);
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
async fn get_pending_proof_by_secret(
|
async fn get_pending_proofs_by_secrets(
|
||||||
&self,
|
&self,
|
||||||
secret: &Secret,
|
secrets: &[Secret],
|
||||||
) -> Result<Option<Proof>, Self::Err> {
|
) -> Result<Vec<Option<Proof>>, Self::Err> {
|
||||||
|
let mut transaction = self.pool.begin().await.map_err(Error::from)?;
|
||||||
|
|
||||||
|
let mut proofs = Vec::with_capacity(secrets.len());
|
||||||
|
|
||||||
|
for secret in secrets {
|
||||||
let rec = sqlx::query(
|
let rec = sqlx::query(
|
||||||
r#"
|
r#"
|
||||||
SELECT *
|
SELECT *
|
||||||
@@ -591,20 +620,30 @@ AND state="PENDING";
|
|||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.bind(secret.to_string())
|
.bind(secret.to_string())
|
||||||
.fetch_one(&self.pool)
|
.fetch_one(&mut transaction)
|
||||||
.await;
|
.await;
|
||||||
|
match rec {
|
||||||
let rec = match rec {
|
Ok(rec) => {
|
||||||
Ok(rec) => rec,
|
proofs.push(Some(sqlite_row_to_proof(rec)?));
|
||||||
|
}
|
||||||
Err(err) => match err {
|
Err(err) => match err {
|
||||||
sqlx::Error::RowNotFound => return Ok(None),
|
sqlx::Error::RowNotFound => proofs.push(None),
|
||||||
_ => return Err(Error::SQLX(err).into()),
|
_ => return Err(Error::SQLX(err).into()),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Some(sqlite_row_to_proof(rec)?))
|
|
||||||
}
|
}
|
||||||
async fn get_pending_proof_by_y(&self, y: &PublicKey) -> Result<Option<Proof>, Self::Err> {
|
transaction.commit().await.map_err(Error::from)?;
|
||||||
|
Ok(proofs)
|
||||||
|
}
|
||||||
|
async fn get_pending_proofs_by_ys(
|
||||||
|
&self,
|
||||||
|
ys: &[PublicKey],
|
||||||
|
) -> Result<Vec<Option<Proof>>, Self::Err> {
|
||||||
|
let mut transaction = self.pool.begin().await.map_err(Error::from)?;
|
||||||
|
|
||||||
|
let mut proofs = Vec::with_capacity(ys.len());
|
||||||
|
|
||||||
|
for y in ys {
|
||||||
let rec = sqlx::query(
|
let rec = sqlx::query(
|
||||||
r#"
|
r#"
|
||||||
SELECT *
|
SELECT *
|
||||||
@@ -614,17 +653,21 @@ AND state="PENDING";
|
|||||||
"#,
|
"#,
|
||||||
)
|
)
|
||||||
.bind(y.to_bytes().to_vec())
|
.bind(y.to_bytes().to_vec())
|
||||||
.fetch_one(&self.pool)
|
.fetch_one(&mut transaction)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let rec = match rec {
|
match rec {
|
||||||
Ok(rec) => rec,
|
Ok(rec) => {
|
||||||
|
proofs.push(Some(sqlite_row_to_proof(rec)?));
|
||||||
|
}
|
||||||
Err(err) => match err {
|
Err(err) => match err {
|
||||||
sqlx::Error::RowNotFound => return Ok(None),
|
sqlx::Error::RowNotFound => proofs.push(None),
|
||||||
_ => return Err(Error::SQLX(err).into()),
|
_ => return Err(Error::SQLX(err).into()),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
Ok(Some(sqlite_row_to_proof(rec)?))
|
}
|
||||||
|
|
||||||
|
Ok(proofs)
|
||||||
}
|
}
|
||||||
async fn remove_pending_proofs(&self, secrets: Vec<&Secret>) -> Result<(), Self::Err> {
|
async fn remove_pending_proofs(&self, secrets: Vec<&Secret>) -> Result<(), Self::Err> {
|
||||||
let mut transaction = self.pool.begin().await.map_err(Error::from)?;
|
let mut transaction = self.pool.begin().await.map_err(Error::from)?;
|
||||||
|
|||||||
@@ -223,17 +223,40 @@ impl MintDatabase for MintMemoryDatabase {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_spent_proof_by_secret(&self, secret: &Secret) -> Result<Option<Proof>, Self::Err> {
|
async fn get_spent_proofs_by_secrets(
|
||||||
Ok(self
|
&self,
|
||||||
.spent_proofs
|
secrets: &[Secret],
|
||||||
.read()
|
) -> Result<Vec<Option<Proof>>, Self::Err> {
|
||||||
.await
|
let spent_proofs = self.spent_proofs.read().await;
|
||||||
.get(&hash_to_curve(&secret.to_bytes())?.to_bytes())
|
|
||||||
.cloned())
|
let mut proofs = Vec::with_capacity(secrets.len());
|
||||||
|
|
||||||
|
for secret in secrets {
|
||||||
|
let y = hash_to_curve(&secret.to_bytes())?;
|
||||||
|
|
||||||
|
let proof = spent_proofs.get(&y.to_bytes()).cloned();
|
||||||
|
|
||||||
|
proofs.push(proof);
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_spent_proof_by_y(&self, y: &PublicKey) -> Result<Option<Proof>, Self::Err> {
|
Ok(proofs)
|
||||||
Ok(self.spent_proofs.read().await.get(&y.to_bytes()).cloned())
|
}
|
||||||
|
|
||||||
|
async fn get_spent_proofs_by_ys(
|
||||||
|
&self,
|
||||||
|
ys: &[PublicKey],
|
||||||
|
) -> Result<Vec<Option<Proof>>, Self::Err> {
|
||||||
|
let spent_proofs = self.spent_proofs.read().await;
|
||||||
|
|
||||||
|
let mut proofs = Vec::with_capacity(ys.len());
|
||||||
|
|
||||||
|
for y in ys {
|
||||||
|
let proof = spent_proofs.get(&y.to_bytes()).cloned();
|
||||||
|
|
||||||
|
proofs.push(proof);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(proofs)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn add_pending_proofs(&self, pending_proofs: Proofs) -> Result<(), Self::Err> {
|
async fn add_pending_proofs(&self, pending_proofs: Proofs) -> Result<(), Self::Err> {
|
||||||
@@ -245,21 +268,40 @@ impl MintDatabase for MintMemoryDatabase {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_pending_proof_by_secret(
|
async fn get_pending_proofs_by_secrets(
|
||||||
&self,
|
&self,
|
||||||
secret: &Secret,
|
secrets: &[Secret],
|
||||||
) -> Result<Option<Proof>, Self::Err> {
|
) -> Result<Vec<Option<Proof>>, Self::Err> {
|
||||||
let secret_point = hash_to_curve(&secret.to_bytes())?;
|
let spent_proofs = self.pending_proofs.read().await;
|
||||||
Ok(self
|
|
||||||
.pending_proofs
|
let mut proofs = Vec::with_capacity(secrets.len());
|
||||||
.read()
|
|
||||||
.await
|
for secret in secrets {
|
||||||
.get(&secret_point.to_bytes())
|
let y = hash_to_curve(&secret.to_bytes())?;
|
||||||
.cloned())
|
|
||||||
|
let proof = spent_proofs.get(&y.to_bytes()).cloned();
|
||||||
|
|
||||||
|
proofs.push(proof);
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_pending_proof_by_y(&self, y: &PublicKey) -> Result<Option<Proof>, Self::Err> {
|
Ok(proofs)
|
||||||
Ok(self.pending_proofs.read().await.get(&y.to_bytes()).cloned())
|
}
|
||||||
|
|
||||||
|
async fn get_pending_proofs_by_ys(
|
||||||
|
&self,
|
||||||
|
ys: &[PublicKey],
|
||||||
|
) -> Result<Vec<Option<Proof>>, Self::Err> {
|
||||||
|
let spent_proofs = self.pending_proofs.read().await;
|
||||||
|
|
||||||
|
let mut proofs = Vec::with_capacity(ys.len());
|
||||||
|
|
||||||
|
for y in ys {
|
||||||
|
let proof = spent_proofs.get(&y.to_bytes()).cloned();
|
||||||
|
|
||||||
|
proofs.push(proof);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(proofs)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn remove_pending_proofs(&self, secrets: Vec<&Secret>) -> Result<(), Self::Err> {
|
async fn remove_pending_proofs(&self, secrets: Vec<&Secret>) -> Result<(), Self::Err> {
|
||||||
|
|||||||
@@ -219,20 +219,29 @@ pub trait MintDatabase {
|
|||||||
|
|
||||||
/// Add spent [`Proofs`]
|
/// Add spent [`Proofs`]
|
||||||
async fn add_spent_proofs(&self, proof: Proofs) -> Result<(), Self::Err>;
|
async fn add_spent_proofs(&self, proof: Proofs) -> Result<(), Self::Err>;
|
||||||
/// Get spent [`Proof`] by secret
|
/// Get spent [`Proofs`] by secrets
|
||||||
async fn get_spent_proof_by_secret(&self, secret: &Secret) -> Result<Option<Proof>, Self::Err>;
|
async fn get_spent_proofs_by_secrets(
|
||||||
/// Get spent [`Proof`] by y
|
&self,
|
||||||
async fn get_spent_proof_by_y(&self, y: &PublicKey) -> Result<Option<Proof>, Self::Err>;
|
secret: &[Secret],
|
||||||
|
) -> Result<Vec<Option<Proof>>, Self::Err>;
|
||||||
|
/// Get spent [`Proofs`] by ys
|
||||||
|
async fn get_spent_proofs_by_ys(
|
||||||
|
&self,
|
||||||
|
y: &[PublicKey],
|
||||||
|
) -> Result<Vec<Option<Proof>>, Self::Err>;
|
||||||
|
|
||||||
/// Add pending [`Proofs`]
|
/// Add pending [`Proofs`]
|
||||||
async fn add_pending_proofs(&self, proof: Proofs) -> Result<(), Self::Err>;
|
async fn add_pending_proofs(&self, proof: Proofs) -> Result<(), Self::Err>;
|
||||||
/// Get pending [`Proof`] by secret
|
/// Get pending [`Proofs`] by secrets
|
||||||
async fn get_pending_proof_by_secret(
|
async fn get_pending_proofs_by_secrets(
|
||||||
&self,
|
&self,
|
||||||
secret: &Secret,
|
secrets: &[Secret],
|
||||||
) -> Result<Option<Proof>, Self::Err>;
|
) -> Result<Vec<Option<Proof>>, Self::Err>;
|
||||||
/// Get pending [`Proof`] by y
|
/// Get pending [`Proofs`] by ys
|
||||||
async fn get_pending_proof_by_y(&self, y: &PublicKey) -> Result<Option<Proof>, Self::Err>;
|
async fn get_pending_proofs_by_ys(
|
||||||
|
&self,
|
||||||
|
ys: &[PublicKey],
|
||||||
|
) -> Result<Vec<Option<Proof>>, Self::Err>;
|
||||||
/// Remove pending [`Proofs`]
|
/// Remove pending [`Proofs`]
|
||||||
async fn remove_pending_proofs(&self, secret: Vec<&Secret>) -> Result<(), Self::Err>;
|
async fn remove_pending_proofs(&self, secret: Vec<&Secret>) -> Result<(), Self::Err>;
|
||||||
|
|
||||||
|
|||||||
@@ -606,15 +606,43 @@ impl Mint {
|
|||||||
|
|
||||||
let proof_count = swap_request.inputs.len();
|
let proof_count = swap_request.inputs.len();
|
||||||
|
|
||||||
let secrets: HashSet<[u8; 33]> = swap_request
|
let secrets: Vec<PublicKey> = swap_request
|
||||||
.inputs
|
.inputs
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|p| hash_to_curve(&p.secret.to_bytes()))
|
.flat_map(|p| hash_to_curve(&p.secret.to_bytes()))
|
||||||
.map(|p| p.to_bytes())
|
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
let pending_proofs: Proofs = self
|
||||||
|
.localstore
|
||||||
|
.get_pending_proofs_by_ys(&secrets)
|
||||||
|
.await?
|
||||||
|
.into_iter()
|
||||||
|
.flatten()
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
if !pending_proofs.is_empty() {
|
||||||
|
return Err(Error::TokenPending);
|
||||||
|
}
|
||||||
|
|
||||||
|
let spent_proofs: Proofs = self
|
||||||
|
.localstore
|
||||||
|
.get_spent_proofs_by_ys(&secrets)
|
||||||
|
.await?
|
||||||
|
.into_iter()
|
||||||
|
.flatten()
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
if !spent_proofs.is_empty() {
|
||||||
|
return Err(Error::TokenAlreadySpent);
|
||||||
|
}
|
||||||
|
|
||||||
// Check that there are no duplicate proofs in request
|
// Check that there are no duplicate proofs in request
|
||||||
if secrets.len().ne(&proof_count) {
|
if secrets
|
||||||
|
.iter()
|
||||||
|
.collect::<HashSet<&PublicKey>>()
|
||||||
|
.len()
|
||||||
|
.ne(&proof_count)
|
||||||
|
{
|
||||||
return Err(Error::DuplicateProofs);
|
return Err(Error::DuplicateProofs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -709,16 +737,6 @@ impl Mint {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let y: PublicKey = hash_to_curve(&proof.secret.to_bytes())?;
|
|
||||||
|
|
||||||
if self.localstore.get_spent_proof_by_y(&y).await?.is_some() {
|
|
||||||
return Err(Error::TokenAlreadySpent);
|
|
||||||
}
|
|
||||||
|
|
||||||
if self.localstore.get_pending_proof_by_y(&y).await?.is_some() {
|
|
||||||
return Err(Error::TokenPending);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.ensure_keyset_loaded(&proof.keyset_id).await?;
|
self.ensure_keyset_loaded(&proof.keyset_id).await?;
|
||||||
let keysets = self.keysets.read().await;
|
let keysets = self.keysets.read().await;
|
||||||
let keyset = keysets.get(&proof.keyset_id).ok_or(Error::UnknownKeySet)?;
|
let keyset = keysets.get(&proof.keyset_id).ok_or(Error::UnknownKeySet)?;
|
||||||
@@ -739,13 +757,28 @@ impl Mint {
|
|||||||
) -> Result<CheckStateResponse, Error> {
|
) -> Result<CheckStateResponse, Error> {
|
||||||
let mut states = Vec::with_capacity(check_state.ys.len());
|
let mut states = Vec::with_capacity(check_state.ys.len());
|
||||||
|
|
||||||
for y in &check_state.ys {
|
let spent_proofs = self
|
||||||
let state = if self.localstore.get_spent_proof_by_y(y).await?.is_some() {
|
.localstore
|
||||||
|
.get_spent_proofs_by_ys(&check_state.ys)
|
||||||
|
.await?;
|
||||||
|
let pending_proofs = self
|
||||||
|
.localstore
|
||||||
|
.get_pending_proofs_by_ys(&check_state.ys)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
for ((spent, pending), y) in spent_proofs
|
||||||
|
.iter()
|
||||||
|
.zip(&pending_proofs)
|
||||||
|
.zip(&check_state.ys)
|
||||||
|
{
|
||||||
|
let state = match (spent, pending) {
|
||||||
|
(None, None) => State::Unspent,
|
||||||
|
(Some(_), None) => State::Spent,
|
||||||
|
(None, Some(_)) => State::Pending,
|
||||||
|
(Some(_), Some(_)) => {
|
||||||
|
tracing::error!("Proof should not be both pending and spent. Assuming Spent");
|
||||||
State::Spent
|
State::Spent
|
||||||
} else if self.localstore.get_pending_proof_by_y(y).await?.is_some() {
|
}
|
||||||
State::Pending
|
|
||||||
} else {
|
|
||||||
State::Unspent
|
|
||||||
};
|
};
|
||||||
|
|
||||||
states.push(ProofState {
|
states.push(ProofState {
|
||||||
@@ -763,6 +796,41 @@ impl Mint {
|
|||||||
&self,
|
&self,
|
||||||
melt_request: &MeltBolt11Request,
|
melt_request: &MeltBolt11Request,
|
||||||
) -> Result<MeltQuote, Error> {
|
) -> Result<MeltQuote, Error> {
|
||||||
|
let secrets: Vec<PublicKey> = melt_request
|
||||||
|
.inputs
|
||||||
|
.iter()
|
||||||
|
.flat_map(|p| hash_to_curve(&p.secret.to_bytes()))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
// Ensure proofs are unique and not being double spent
|
||||||
|
if melt_request.inputs.len() != secrets.iter().collect::<HashSet<_>>().len() {
|
||||||
|
return Err(Error::DuplicateProofs);
|
||||||
|
}
|
||||||
|
|
||||||
|
let pending_proofs: Proofs = self
|
||||||
|
.localstore
|
||||||
|
.get_pending_proofs_by_ys(&secrets)
|
||||||
|
.await?
|
||||||
|
.into_iter()
|
||||||
|
.flatten()
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
if !pending_proofs.is_empty() {
|
||||||
|
return Err(Error::TokenPending);
|
||||||
|
}
|
||||||
|
|
||||||
|
let spent_proofs: Proofs = self
|
||||||
|
.localstore
|
||||||
|
.get_spent_proofs_by_ys(&secrets)
|
||||||
|
.await?
|
||||||
|
.into_iter()
|
||||||
|
.flatten()
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
if !spent_proofs.is_empty() {
|
||||||
|
return Err(Error::TokenAlreadySpent);
|
||||||
|
}
|
||||||
|
|
||||||
for proof in &melt_request.inputs {
|
for proof in &melt_request.inputs {
|
||||||
self.verify_proof(proof).await?;
|
self.verify_proof(proof).await?;
|
||||||
}
|
}
|
||||||
@@ -858,18 +926,6 @@ impl Mint {
|
|||||||
return Err(Error::MultipleUnits);
|
return Err(Error::MultipleUnits);
|
||||||
}
|
}
|
||||||
|
|
||||||
let secrets: HashSet<[u8; 33]> = melt_request
|
|
||||||
.inputs
|
|
||||||
.iter()
|
|
||||||
.flat_map(|p| hash_to_curve(&p.secret.to_bytes()))
|
|
||||||
.map(|p| p.to_bytes())
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
// Ensure proofs are unique and not being double spent
|
|
||||||
if melt_request.inputs.len().ne(&secrets.len()) {
|
|
||||||
return Err(Error::DuplicateProofs);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add proofs to pending
|
// Add proofs to pending
|
||||||
self.localstore
|
self.localstore
|
||||||
.add_pending_proofs(melt_request.inputs.clone())
|
.add_pending_proofs(melt_request.inputs.clone())
|
||||||
|
|||||||
Reference in New Issue
Block a user