Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
Dzejkop committed Oct 21, 2024
1 parent f30275b commit 428daf1
Show file tree
Hide file tree
Showing 18 changed files with 346 additions and 883 deletions.
11 changes: 4 additions & 7 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,14 @@ Sequencer has 6 API routes.
indeed in the tree. The inclusion proof is then returned to the API caller.
3. `/deleteIdentity` - Takes an identity commitment hash, ensures that it exists and hasn't been deleted yet. This
identity is then scheduled for deletion.
4. `/recoverIdentity` - Takes two identity commitment hashes. The first must exist and will be scheduled for deletion
and the other will be inserted as a replacement after the first identity has been deleted and a set amount of time (
depends on configuration parameters) has passed.
5. `/verifySemaphoreProof` - This call takes root, signal hash, nullifier hash, external nullifier hash and a proof.
4. `/verifySemaphoreProof` - This call takes root, signal hash, nullifier hash, external nullifier hash and a proof.
The proving key is fetched based on the depth index, and verification key as well.
The list of prime fields is created based on request input mentioned before, and then we proceed to verify the proof.
Sequencer uses groth16 zk-SNARK implementation.
The API call returns the proof as a response.
6. `/addBatchSize` - Adds a prover with specific batch size to a list of provers.
7. `/removeBatchSize` - Removes the prover based on batch size.
8. `/listBatchSizes` - Lists all provers that are added to the Sequencer.
5. `/addBatchSize` - Adds a prover with specific batch size to a list of provers.
6. `/removeBatchSize` - Removes the prover based on batch size.
7. `/listBatchSizes` - Lists all provers that are added to the Sequencer.

## Getting Started

Expand Down
13 changes: 13 additions & 0 deletions schemas/database/016_remove_recovery.down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CREATE TABLE recoveries (
existing_commitment BYTEA NOT NULL UNIQUE,
new_commitment BYTEA NOT NULL UNIQUE
);

ALTER TABLE unprocessed_identities
ADD COLUMN eligibility TIMESTAMPTZ,
ADD COLUMN status VARCHAR(50) NOT NULL,
ADD COLUMN processed_at TIMESTAMPTZ,
ADD COLUMN error_message TEXT;

ALTER TABLE unprocessed_identities
DROP CONSTRAINT unique_commitment;
11 changes: 11 additions & 0 deletions schemas/database/016_remove_recovery.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
DROP TABLE recoveries;

ALTER TABLE unprocessed_identities
DROP COLUMN eligibility,
DROP COLUMN status,
DROP COLUMN processed_at,
DROP COLUMN error_message;

ALTER TABLE unprocessed_identities
ADD CONSTRAINT unique_commitment UNIQUE (commitment);

29 changes: 0 additions & 29 deletions schemas/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -62,26 +62,6 @@ paths:
schema:
description: 'Identity could not be queued for deletion'
type: 'string'
/recoverIdentity:
post:
summary: 'Queues a recovery request, deleting the previous identity specified and inserting the new one.
New insertions must wait a specified time delay before being included in the merkle tree'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RecoveryRequest'
responses:
'202':
description: 'Identity has been successfully queued for recovery'
'400':
description: 'Invalid request'
content:
application/json:
schema:
description: 'Identity could not be queued for recovery'
type: 'string'
/inclusionProof:
post:
summary: 'Get Merkle inclusion proof'
Expand Down Expand Up @@ -152,15 +132,6 @@ paths:

components:
schemas:
RecoveryRequest:
type: object
properties:
previousIdentityCommitment:
type: string
pattern: '^[A-F0-9]{64}$'
newIdentityCommitment:
type: string
pattern: '^[A-F0-9]{64}$'
IdentityCommitment:
type: object
properties:
Expand Down
100 changes: 19 additions & 81 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,22 @@ use std::sync::{Arc, OnceLock};
use chrono::{Duration, Utc};
use ruint::Uint;
use semaphore::protocol::verify_proof;
use sqlx::{Postgres, Transaction};
use tracing::{info, instrument, warn};

use crate::config::Config;
use crate::contracts::IdentityManager;
use crate::database::methods::DbMethods as _;
use crate::database::Database;
use crate::database::{Database, IsolationLevel};
use crate::ethereum::Ethereum;
use crate::identity::processor::{
IdentityProcessor, OffChainIdentityProcessor, OnChainIdentityProcessor,
};
use crate::identity::validator::IdentityValidator;
use crate::identity_tree::initializer::TreeInitializer;
use crate::identity_tree::{Hash, InclusionProof, RootItem, TreeState, TreeVersionReadOps};
use crate::identity_tree::{Hash, InclusionProof, RootItem, TreeState, TreeVersionOps};
use crate::prover::map::initialize_prover_maps;
use crate::prover::repository::ProverRepository;
use crate::prover::{ProverConfig, ProverType};
use crate::retry_tx;
use crate::server::data::{
InclusionProofResponse, ListBatchSizesResponse, VerifySemaphoreProofQuery,
VerifySemaphoreProofRequest, VerifySemaphoreProofResponse,
Expand Down Expand Up @@ -157,22 +155,19 @@ impl App {

// TODO: ensure that the id is not in the tree or in unprocessed identities

if self.database.identity_exists(commitment).await? {
let mut tx = self
.database
.begin_tx(IsolationLevel::ReadCommitted)
.await?;

if tx.identity_exists(commitment).await? {
return Err(ServerError::DuplicateCommitment);
}

self.database
.insert_new_identity(commitment, Utc::now())
.await?;
tx.insert_unprocessed_identity(commitment, Utc::now()).await?;

Ok(())
}
tx.commit().await?;

pub async fn delete_identity_tx(&self, commitment: &Hash) -> Result<(), ServerError> {
retry_tx!(self.database.pool, tx, {
self.delete_identity(&mut tx, commitment).await
})
.await?;
Ok(())
}

Expand All @@ -182,12 +177,13 @@ impl App {
///
/// Will return `Err` if identity is already queued, not in the tree, or the
/// queue malfunctions.
#[instrument(level = "debug", skip(self, tx))]
pub async fn delete_identity(
&self,
tx: &mut Transaction<'_, Postgres>,
commitment: &Hash,
) -> Result<(), ServerError> {
#[instrument(level = "debug", skip(self))]
pub async fn delete_identity(&self, commitment: &Hash) -> Result<(), ServerError> {
let mut tx = self
.database
.begin_tx(IsolationLevel::RepeatableRead)
.await?;

// Ensure that deletion provers exist
if !self.prover_repository.has_deletion_provers().await {
warn!(
Expand All @@ -213,76 +209,18 @@ impl App {
return Err(ServerError::IdentityAlreadyDeleted);
}

// Check if the id is already queued for deletion
if tx.identity_is_queued_for_deletion(commitment).await? {
return Err(ServerError::IdentityQueuedForDeletion);
}

// Check if there are any deletions, if not, set the latest deletion timestamp
// to now to ensure that the new deletion is processed by the next deletion
// interval
if tx.get_deletions().await?.is_empty() {
tx.update_latest_deletion(Utc::now()).await?;
}

// If the id has not been deleted, insert into the deletions table
tx.insert_new_deletion(leaf_index, commitment).await?;

Ok(())
}

/// Queues a recovery of an identity.
///
/// i.e. deletion and reinsertion after a set period of time.
///
/// # Errors
///
/// Will return `Err` if identity is already queued for deletion, not in the
/// tree, or the queue malfunctions.
#[instrument(level = "debug", skip(self))]
pub async fn recover_identity(
&self,
existing_commitment: &Hash,
new_commitment: &Hash,
) -> Result<(), ServerError> {
retry_tx!(self.database.pool, tx, {
if self.identity_validator.is_initial_leaf(new_commitment) {
warn!(
?new_commitment,
"Attempt to insert initial leaf in recovery."
);
return Err(ServerError::InvalidCommitment);
}
tx.commit().await?;

if !self.prover_repository.has_insertion_provers().await {
warn!(
?new_commitment,
"Identity Manager has no provers. Add provers with /addBatchSize request."
);
return Err(ServerError::NoProversOnIdInsert);
}

if !self.identity_validator.is_reduced(*new_commitment) {
warn!(
?new_commitment,
"The new identity commitment is not reduced."
);
return Err(ServerError::UnreducedCommitment);
}

if tx.identity_exists(*new_commitment).await? {
return Err(ServerError::DuplicateCommitment);
}

// Delete the existing id and insert the commitments into the recovery table
self.delete_identity(&mut tx, existing_commitment).await?;

tx.insert_new_recovery(existing_commitment, new_commitment)
.await?;

Ok(())
})
.await
Ok(())
}

fn merge_env_provers(
Expand Down
Loading

0 comments on commit 428daf1

Please sign in to comment.