Skip to content

Commit

Permalink
Fix the logic, make it work
Browse files Browse the repository at this point in the history
Signed-off-by: Shota Jolbordi <shota.jolbordi@iohk.io>
  • Loading branch information
Shota Jolbordi committed Dec 13, 2023
1 parent 478a7cc commit 6e49fcd
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,6 @@ private class CredentialServiceImpl(
case value => ZIO.fail(UnsupportedCredentialFormat(value))

_ <- validateCredentialOfferAttachment(credentialFormat, attachment)

record <- ZIO.succeed(
IssueCredentialRecord(
id = DidCommID(),
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -1034,45 +1032,33 @@ 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)
size = currentStatusList.size
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)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"""
Expand All @@ -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

Expand All @@ -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()
Expand Down Expand Up @@ -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)
Expand All @@ -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 =
Expand All @@ -110,8 +140,7 @@ class JdbcCredentialStatusListRepository(xa: Transactor[ContextAwareTask], xb: T
_ <- statusListEntryCreationQuery
_ <- statusListUpdateQuery
} yield ()



res.transactWallet(xa)

}
Expand Down

0 comments on commit 6e49fcd

Please sign in to comment.