Skip to content

Commit

Permalink
Merge pull request #646 from 0xPolygonID/PID-2055-issuer-node-fix-pub…
Browse files Browse the repository at this point in the history
…lish-state-action

fix: publish state and improve performance when processing takes place
  • Loading branch information
martinsaporiti authored Apr 11, 2024
2 parents 2b872e4 + a65ef21 commit a6a1550
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 32 deletions.
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

0 comments on commit a6a1550

Please sign in to comment.