From 6e49fcd7cd1cba99860b4104e142fe313a11ffe2 Mon Sep 17 00:00:00 2001 From: Shota Jolbordi Date: Thu, 14 Dec 2023 02:11:28 +0400 Subject: [PATCH] Fix the logic, make it work Signed-off-by: Shota Jolbordi --- .../CredentialStatusListRepository.scala | 4 +- .../core/service/CredentialServiceImpl.scala | 28 +++------- .../JdbcCredentialStatusListRepository.scala | 55 ++++++++++++++----- 3 files changed, 51 insertions(+), 36 deletions(-) diff --git a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/repository/CredentialStatusListRepository.scala b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/repository/CredentialStatusListRepository.scala index a79dde5bb1..ba119426bf 100644 --- a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/repository/CredentialStatusListRepository.scala +++ b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/repository/CredentialStatusListRepository.scala @@ -12,9 +12,9 @@ import zio.* import java.util.UUID trait CredentialStatusListRepository { - def getLatestOfTheWallet(walletId: WalletId): RIO[WalletAccessContext, Option[CredentialStatusList]] + def getLatestOfTheWallet: RIO[WalletAccessContext, Option[CredentialStatusList]] - def createNewForTheWallet(walletId: WalletId, jwtIssuer: Issuer): RIO[WalletAccessContext, CredentialStatusList] + def createNewForTheWallet(jwtIssuer: Issuer): RIO[WalletAccessContext, CredentialStatusList] def allocateSpaceForCredential( issueCredentialRecordId: DidCommID, diff --git a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/CredentialServiceImpl.scala b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/CredentialServiceImpl.scala index 083fb5caa2..c051c4b982 100644 --- a/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/CredentialServiceImpl.scala +++ b/pollux/lib/core/src/main/scala/io/iohk/atala/pollux/core/service/CredentialServiceImpl.scala @@ -259,7 +259,6 @@ private class CredentialServiceImpl( case value => ZIO.fail(UnsupportedCredentialFormat(value)) _ <- validateCredentialOfferAttachment(credentialFormat, attachment) - record <- ZIO.succeed( IssueCredentialRecord( id = DidCommID(), @@ -1003,8 +1002,7 @@ private class CredentialServiceImpl( payload => ZIO.logInfo("JWT Presentation Validation Successful!") ) issuanceDate = Instant.now() - walletId <- ZIO.serviceWith[WalletAccessContext](_.walletId) - credentialStatus <- allocateNewCredentialInStatusListForWallet(walletId, record) + credentialStatus <- allocateNewCredentialInStatusListForWallet(record) // TODO: get schema when schema registry is available if schema ID is provided w3Credential = W3cCredentialPayload( `@context` = Set( @@ -1034,28 +1032,19 @@ private class CredentialServiceImpl( record <- markCredentialGenerated(record, issueCredential) } yield record } - - // what needs to happen: - // get the last status list of this wallet that was created - // if statusList does not even exists, create one - // check its size and last used index - // if last used index is less then size, that is the status list we will use, status list index is last_used_index + 1 - // if the last used index is equals to the size create new status list for this wallet, and use that, status list_index is 0 - // in both cases, after aquring status list to be used, - // - + private[this] def allocateNewCredentialInStatusListForWallet( - walletId: WalletId, record: IssueCredentialRecord ): ZIO[WalletAccessContext, CredentialServiceError, CredentialStatus] = { + // TODO: reactor, use STM to perform all effects atomically for { - lastStatusList <- credentialStatusListRepository.getLatestOfTheWallet(walletId).mapError(RepositoryError.apply) + lastStatusList <- credentialStatusListRepository.getLatestOfTheWallet.mapError(RepositoryError.apply) issuingDID <- ZIO .fromOption(record.issuingDID) .mapError(_ => UnexpectedError(s"Issuing Id not found in record: ${record.id.value}")) jwtIssuer <- createJwtIssuer(issuingDID, VerificationRelationship.AssertionMethod) currentStatusList <- lastStatusList - .fold(credentialStatusListRepository.createNewForTheWallet(walletId, jwtIssuer))( + .fold(credentialStatusListRepository.createNewForTheWallet(jwtIssuer))( ZIO.succeed(_) ) .mapError(RepositoryError.apply) @@ -1063,16 +1052,13 @@ private class CredentialServiceImpl( lastUsedIndex = currentStatusList.lastUsedIndex statusListToBeUsed <- if lastUsedIndex < size then ZIO.succeed(currentStatusList) - else credentialStatusListRepository.createNewForTheWallet(walletId, jwtIssuer).mapError(RepositoryError.apply) + else credentialStatusListRepository.createNewForTheWallet(jwtIssuer).mapError(RepositoryError.apply) - // creates record in credentials_in_status_list table with provided recordId, credentialStatusListId and statusListIndex - // after that updates credentialStatusLists table, sets lastUsedIndex = statusListIndex - // all of this needs to happen in one postgres transaction _ <- credentialStatusListRepository .allocateSpaceForCredential( issueCredentialRecordId = record.id, credentialStatusListId = statusListToBeUsed.id, - statusListIndex = lastUsedIndex + 1 + statusListIndex = statusListToBeUsed.lastUsedIndex + 1 ) .mapError(RepositoryError.apply) diff --git a/pollux/lib/sql-doobie/src/main/scala/io/iohk/atala/pollux/sql/repository/JdbcCredentialStatusListRepository.scala b/pollux/lib/sql-doobie/src/main/scala/io/iohk/atala/pollux/sql/repository/JdbcCredentialStatusListRepository.scala index 37c2afcc0b..0689ef3c65 100644 --- a/pollux/lib/sql-doobie/src/main/scala/io/iohk/atala/pollux/sql/repository/JdbcCredentialStatusListRepository.scala +++ b/pollux/lib/sql-doobie/src/main/scala/io/iohk/atala/pollux/sql/repository/JdbcCredentialStatusListRepository.scala @@ -21,7 +21,7 @@ import java.util.UUID class JdbcCredentialStatusListRepository(xa: Transactor[ContextAwareTask], xb: Transactor[Task]) extends CredentialStatusListRepository { - def getLatestOfTheWallet(walletId: WalletId): RIO[WalletAccessContext, Option[CredentialStatusList]] = { + def getLatestOfTheWallet: RIO[WalletAccessContext, Option[CredentialStatusList]] = { val cxnIO = sql""" @@ -32,10 +32,12 @@ class JdbcCredentialStatusListRepository(xa: Transactor[ContextAwareTask], xb: T | issued, | purpose, | status_list_jwt_credential, + | size, + | last_used_index, | created_at, | updated_at - | from public.credential_status_lists order by created_at DESC limit 1 - |""" + | FROM public.credential_status_lists order by created_at DESC limit 1 + |""".stripMargin .query[CredentialStatusList] .option @@ -44,7 +46,7 @@ class JdbcCredentialStatusListRepository(xa: Transactor[ContextAwareTask], xb: T } - def createNewForTheWallet(walletId: WalletId, jwtIssuer: Issuer): RIO[WalletAccessContext, CredentialStatusList] = { + def createNewForTheWallet(jwtIssuer: Issuer): RIO[WalletAccessContext, CredentialStatusList] = { val id = UUID.randomUUID() val issued = Instant.now() @@ -72,11 +74,27 @@ class JdbcCredentialStatusListRepository(xa: Transactor[ContextAwareTask], xb: T for { jwtCredential <- encodedJwtCredential query = sql""" - |INSERT INTO public.credential_status_lists (id, wallet_id, issuer, issued, purpose, - | status_list_jwt_credential, size, last_used_index) - |VALUES ($id, ${walletId.toUUID}, $issuerDid, $issued, ${StatusPurpose.Revocation.str}, ${jwtCredential.value}, - | ${BitString.MIN_SL2021_SIZE}, 0) - |RETURNING id, wallet_id, issuer, issued, purpose, status_list_jwt_credential, created_at, updated_at + |INSERT INTO public.credential_status_lists ( + | id, + | issuer, + | issued, + | purpose, + | status_list_jwt_credential, + | size, + | last_used_index, + | wallet_id + | ) + |VALUES ( + | $id, + | $issuerDid, + | $issued, + | ${StatusPurpose.Revocation}::public.enum_credential_status_list_purpose, + | ${jwtCredential.value}, + | ${BitString.MIN_SL2021_SIZE}, + | 0, + | current_setting('app.current_wallet_id')::UUID + | ) + |RETURNING id, wallet_id, issuer, issued, purpose, status_list_jwt_credential, size, last_used_index, created_at, updated_at """.stripMargin.query[CredentialStatusList].unique newStatusList <- query .transactWallet(xa) @@ -92,8 +110,20 @@ class JdbcCredentialStatusListRepository(xa: Transactor[ContextAwareTask], xb: T val statusListEntryCreationQuery = sql""" - | INSERT INTO public.credentials_in_status_list (id, issue_credential_record_id, credential_status_list_id, status_list_index, is_canceled) - | VALUES (${UUID.randomUUID()}, $issueCredentialRecordId, $credentialStatusListId, $statusListIndex, false) + | INSERT INTO public.credentials_in_status_list ( + | id, + | issue_credential_record_id, + | credential_status_list_id, + | status_list_index, + | is_canceled + | ) + | VALUES ( + | ${UUID.randomUUID()}, + | $issueCredentialRecordId, + | $credentialStatusListId, + | $statusListIndex, + | false + | ) |""".stripMargin.update.run val statusListUpdateQuery = @@ -110,8 +140,7 @@ class JdbcCredentialStatusListRepository(xa: Transactor[ContextAwareTask], xb: T _ <- statusListEntryCreationQuery _ <- statusListUpdateQuery } yield () - - + res.transactWallet(xa) }