Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: publish state and improve performance when processing takes place #646

Merged
merged 2 commits into from
Apr 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 34 additions & 30 deletions internal/core/services/identity.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ var (
// ErrAssigningMTPProof - represents an error in the identity metadata
ErrAssigningMTPProof = errors.New("error assigning the MTP Proof from Auth Claim. If this identity has keyType=ETH you must to publish the state first")
// ErrNoClaimsFoundToProcess - means that there are no claims to process
ErrNoClaimsFoundToProcess = errors.New("no MTP claims found to process")
ErrNoClaimsFoundToProcess = errors.New("no MTP or revoked claims found to process")
)

type identity struct {
Expand Down Expand Up @@ -327,42 +327,35 @@ func (i *identity) UpdateState(ctx context.Context, did w3c.DID) (*domain.Identi
return fmt.Errorf("error getting the identifier last state: %w", err)
}

var state *merkletree.Hash = nil
if previousState != nil {
state = previousState.TreeState().State
}

lc, err := i.claimsRepository.GetAllByState(ctx, tx, &did, state)
// Get all mtp claims with state == nil
claimsAddedToTree, err := i.processClaims(ctx, tx, did, iTrees)
if err != nil {
return fmt.Errorf("error getting the states: %w", err)
return err
}

// Check if there are claims to process
if err := checkClaimsToAdd(lc); err != nil {
// Get all revocations with domain.RevPending status
updatedRevocations, err := i.revocationRepository.UpdateStatus(ctx, tx, &did)
if err != nil {
log.Error(ctx, "updating revocation status", "err", err)
return err
}

for i := range lc {
if lc[i].IdentityState == nil {
err = iTrees.AddClaim(ctx, &lc[i])
if err != nil {
return err
}
}
log.Info(ctx, "updating revocation status", "revocations", len(updatedRevocations))

if len(updatedRevocations) == 0 && !claimsAddedToTree {
log.Info(ctx, "no claims or revocations found to process")
return ErrNoClaimsFoundToProcess
}

err = populateIdentityState(ctx, iTrees, newState, previousState)
if err != nil {
log.Error(ctx, "populating identity state", "err", err)
return err
}

err = i.update(ctx, tx, &did, *newState)
if err != nil {
return err
}

updatedRevocations, err := i.revocationRepository.UpdateStatus(ctx, tx, &did)
if err != nil {
log.Error(ctx, "updating claims", "err", err)
return err
}

Expand Down Expand Up @@ -403,17 +396,28 @@ func (i *identity) UpdateState(ctx context.Context, did w3c.DID) (*domain.Identi
return newState, err
}

// checkClaimsToAdd checks if there are claims to process
// if the len of the claims is 0 or the len is 1 and the claim is the authBJJCredential then return an error
func checkClaimsToAdd(lc []domain.Claim) error {
if len(lc) == 0 {
return ErrNoClaimsFoundToProcess
func (i *identity) processClaims(ctx context.Context, tx pgx.Tx, did w3c.DID, iTrees *domain.IdentityMerkleTrees) (bool, error) {
lc, err := i.claimsRepository.GetAllByState(ctx, tx, &did, nil)
if err != nil {
return false, fmt.Errorf("error getting the states: %w", err)
}

if len(lc) == 1 && lc[0].SchemaType == domain.AuthBJJCredentialTypeID {
return ErrNoClaimsFoundToProcess
claimsAddedToTree := false
if len(lc) > 0 {
log.Info(ctx, "adding claims to tree", "claims", len(lc))
claimsAddedToTree = true
}
return nil

for i := range lc {
err = iTrees.AddClaim(ctx, &lc[i])
if err != nil {
log.Error(ctx, "adding claim to tree", "err", err)
return false, err
}

}

return claimsAddedToTree, nil
}

func (i *identity) UpdateIdentityState(ctx context.Context, state *domain.IdentityState) error {
Expand Down
51 changes: 50 additions & 1 deletion internal/core/services/tests/identity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func Test_identity_UpdateState(t *testing.T) {
assert.NotNil(t, identityState.RevocationTreeRoot)
})

t.Run("should return an error after revoke a credential", func(t *testing.T) {
t.Run("should return success after revoke a MTP credential", func(t *testing.T) {
ctx := context.Background()
merklizedRootPosition := "index"
claim, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject,
Expand All @@ -121,7 +121,56 @@ func Test_identity_UpdateState(t *testing.T) {

assert.NoError(t, claimsService.Revoke(ctx, *did, uint64(claim.RevNonce), ""))
_, err = identityService.UpdateState(ctx, *did)
assert.NoError(t, err)
})

t.Run("should return pass after creating two credentials", func(t *testing.T) {
ctx := context.Background()
merklizedRootPosition := "index"
claimMTP, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject,
common.ToPointer(time.Now()), typeC, nil, nil, &merklizedRootPosition,
common.ToPointer(false), common.ToPointer(true), nil, false,
verifiable.SparseMerkleTreeProof, nil, nil, nil))

assert.NoError(t, err)
previousStateIdentity, _ := identityStateRepo.GetLatestStateByIdentifier(ctx, storage.Pgx, did)
identityState, err := identityService.UpdateState(ctx, *did)
assert.NoError(t, err)
assert.Equal(t, did.String(), identityState.Identifier)
assert.NotNil(t, identityState.State)
assert.Equal(t, domain.StatusCreated, identityState.Status)
assert.NotNil(t, identityState.StateID)
assert.Equal(t, previousStateIdentity.State, identityState.PreviousState)
assert.NotNil(t, identityState.RootOfRoots)
assert.NotNil(t, identityState.ClaimsTreeRoot)
assert.NotNil(t, identityState.RevocationTreeRoot)

assert.NoError(t, claimsService.Revoke(ctx, *did, uint64(claimMTP.RevNonce), ""))
_, err = identityService.UpdateState(ctx, *did)
assert.NoError(t, err)

claimSIG, err := claimsService.Save(ctx, ports.NewCreateClaimRequest(did, schema, credentialSubject,
common.ToPointer(time.Now()), typeC, nil, nil, &merklizedRootPosition,
common.ToPointer(true), common.ToPointer(false), nil, false,
verifiable.SparseMerkleTreeProof, nil, nil, nil))

assert.NoError(t, err)
_, err = identityService.UpdateState(ctx, *did)
assert.Error(t, err)

assert.NoError(t, claimsService.Revoke(ctx, *did, uint64(claimSIG.RevNonce), ""))
identityState, err = identityService.UpdateState(ctx, *did)
assert.NoError(t, err)
previousStateIdentity, err = identityStateRepo.GetLatestStateByIdentifier(ctx, storage.Pgx, did)
assert.NoError(t, err)
assert.Equal(t, did.String(), identityState.Identifier)
assert.NotNil(t, identityState.State)
assert.Equal(t, domain.StatusCreated, identityState.Status)
assert.NotNil(t, identityState.StateID)
assert.Equal(t, previousStateIdentity.State, identityState.PreviousState)
assert.NotNil(t, identityState.RootOfRoots)
assert.NotNil(t, identityState.ClaimsTreeRoot)
assert.NotNil(t, identityState.RevocationTreeRoot)
})

t.Run("should get an error creating credential with sig proof", func(t *testing.T) {
Expand Down
1 change: 1 addition & 0 deletions internal/gateways/publisher.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ func (p *publisher) publishState(ctx context.Context, identifier *w3c.DID) (*dom

txID, err := p.publishProof(ctx, identifier, *updatedState)
if err != nil {
// TODO: Handle RHS status already published
log.Error(ctx, "Error during publishing proof:", "err", err, "did", identifier.String())
updatedState.Status = domain.StatusFailed
errUpdating := p.identityService.UpdateIdentityState(ctx, updatedState)
Expand Down
2 changes: 1 addition & 1 deletion internal/repositories/claims.go
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,7 @@ func (c *claims) GetAllByState(ctx context.Context, conn db.Querier, did *w3c.DI
credential_status,
core_claim
FROM claims
WHERE issuer = $1 AND identity_state IS NULL AND identifier = issuer AND (mtp = true OR revoked = true)
WHERE issuer = $1 AND identity_state IS NULL AND identifier = issuer AND mtp = true
`, did.String())
} else {
rows, err = conn.Query(ctx, `
Expand Down
Loading