From 12574cae7683b347a40b9bb5dc111de036a1ff1e Mon Sep 17 00:00:00 2001 From: Jason Sherman Date: Thu, 20 Jul 2023 12:38:02 -0700 Subject: [PATCH] Add revocation registry rotate to faber demo Signed-off-by: Jason Sherman --- aries_cloudagent/revocation/indy.py | 4 +-- demo/README.md | 10 ++++-- demo/runners/faber.py | 53 +++++++++++++++++++++++++++-- 3 files changed, 61 insertions(+), 6 deletions(-) diff --git a/aries_cloudagent/revocation/indy.py b/aries_cloudagent/revocation/indy.py index 1de7463bd1..89333aa75e 100644 --- a/aries_cloudagent/revocation/indy.py +++ b/aries_cloudagent/revocation/indy.py @@ -124,15 +124,15 @@ async def decommission_registry(self, cred_def_id: str): filter(lambda r: r.state != IssuerRevRegRecord.STATE_INIT, registries) ) - init = True for rec in recs: LOGGER.debug(f"decommission {rec.state} rev. reg.") LOGGER.debug(f"revoc_reg_id: {rec.revoc_reg_id}") LOGGER.debug(f"cred_def_id: {cred_def_id}") + # decommission active registry, we need to init a replacement + init = IssuerRevRegRecord.STATE_ACTIVE == rec.state await self._set_registry_status( rec.revoc_reg_id, IssuerRevRegRecord.STATE_DECOMMISSIONED, init ) - init = False # only call init once. return recs diff --git a/demo/README.md b/demo/README.md index a8c4a63573..b3f05c99fb 100644 --- a/demo/README.md +++ b/demo/README.md @@ -229,6 +229,8 @@ Faber will setup support for revocation automatically, and you will see an extra (4) Create New Invitation (5) Revoke Credential (6) Publish Revocations + (7) Rotate Revocation Registry + (8) List Revocation Registries (T) Toggle tracing on credential/proof exchange (X) Exit? ``` @@ -243,14 +245,18 @@ Faber | Credential revocation ID: 1 When you revoke a credential you will need to provide those values: ``` -[1/2/3/4/5/6/T/X] 5 +[1/2/3/4/5/6/7/8/T/X] 5 Enter revocation registry ID: WGmUNAdH2ZfeGvacFoMVVP:4:WGmUNAdH2ZfeGvacFoMVVP:3:CL:38:Faber.Agent.degree_schema:CL_ACCUM:15ca49ed-1250-4608-9e8f-c0d52d7260c3 Enter credential revocation ID: 1 Publish now? [Y/N]: y ``` -Note that you need to Publish the revocation information to the ledger. Once you've revoked a credential any proof which uses this credential will fail to verify. +Note that you need to Publish the revocation information to the ledger. Once you've revoked a credential any proof which uses this credential will fail to verify. + +Rotating the revocation registry will decommission any "ready" registry records and create 2 new registry records. You can view in the logs as the records are created and transition to 'active'. There should always be 2 'active' revocation registries - one working and one for hot-swap. Note that revocation information can still be published from decommissioned registries. + +You can also list the created registries, filtering by current state: 'init', 'generated', 'posted', 'active', 'full', 'decommissioned'. ### DID Exchange diff --git a/demo/runners/faber.py b/demo/runners/faber.py index db892049af..5a26eb2669 100644 --- a/demo/runners/faber.py +++ b/demo/runners/faber.py @@ -443,14 +443,19 @@ async def main(args): " (4) Create New Invitation\n" ) if faber_agent.revocation: - options += " (5) Revoke Credential\n" " (6) Publish Revocations\n" + options += ( + " (5) Revoke Credential\n" + " (6) Publish Revocations\n" + " (7) Rotate Revocation Registry\n" + " (8) List Revocation Registries\n" + ) if faber_agent.endorser_role and faber_agent.endorser_role == "author": options += " (D) Set Endorser's DID\n" if faber_agent.multitenant: options += " (W) Create and/or Enable Wallet\n" options += " (T) Toggle tracing on credential/proof exchange\n" options += " (X) Exit?\n[1/2/3/4/{}{}T/X] ".format( - "5/6/" if faber_agent.revocation else "", + "5/6/7/8/" if faber_agent.revocation else "", "W/" if faber_agent.multitenant else "", ) async for option in prompt_loop(options): @@ -733,6 +738,50 @@ async def main(args): ) except ClientError: pass + elif option == "7" and faber_agent.revocation: + try: + resp = await faber_agent.agent.admin_POST( + f"/revocation/active-registry/{faber_agent.cred_def_id}/rotate", + {}, + ) + faber_agent.agent.log( + "Rotated registries for {}. Decommissioned Registries: {}".format( + faber_agent.cred_def_id, + json.dumps([r for r in resp["rev_reg_ids"]], indent=4), + ) + ) + except ClientError: + pass + elif option == "8" and faber_agent.revocation: + states = [ + "init", + "generated", + "posted", + "active", + "full", + "decommissioned", + ] + state = ( + await prompt( + f"Filter by state: {states}: ", + default="active", + ) + ).strip() + if state not in states: + state = "active" + try: + resp = await faber_agent.agent.admin_GET( + "/revocation/registries/created", + params={"state": state}, + ) + faber_agent.agent.log( + "Registries (state = '{}'): {}".format( + state, + json.dumps([r for r in resp["rev_reg_ids"]], indent=4), + ) + ) + except ClientError: + pass if faber_agent.show_timing: timing = await faber_agent.agent.fetch_timing()