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

Add /rotate to revocation api. #2523

Merged

Conversation

usingtechnology
Copy link
Contributor

Added in handle_full_registry but seems to be some issues with how the counts work.
Cannot set the next_index to start at 0 because the credential data is invalid.
And because we don't track the index and current revocation id externally, we can't trigger the handle_full_registry until after a credential is created. So for every list/index we lose 1 slot. The only way I could successfully have registries rollover AND create the credentials successfully was triggering 1 slot before the max. cred. num.

Added in handle full registry but there are some issues to discuss there...

Signed-off-by: Jason Sherman <tools@usingtechnolo.gy>
@sonarcloud
Copy link

sonarcloud bot commented Oct 2, 2023

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
No Duplication information No Duplication information

@usingtechnology
Copy link
Contributor Author

I am adding more context for the issues I hit dealing with rev list indexes/cred revocation id

First, this is when I set the starting "next_index" to zero...

This is the holder side exception:

Credential: state = credential-received, cred_ex_id = b98bbfcd-385c-4729-9950-8f52442e475f
2023-10-03 16:27:41,207 aries_cloudagent.protocols.issue_credential.v2_0.formats.indy.handler ERROR Error storing credential: None - Error processing received credential
2023-10-03 16:27:41,208 aries_cloudagent.messaging.base_handler ERROR Error storing issued credential
Traceback (most recent call last):
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/anoncreds/holder.py", line 198, in store_credential
    cred_recvd = await asyncio.get_event_loop().run_in_executor(
  File "/usr/local/lib/python3.9/asyncio/futures.py", line 284, in __await__
    yield self  # This tells Task to wait for completion.
  File "/usr/local/lib/python3.9/asyncio/tasks.py", line 328, in __wakeup
Credential: state = abandoned, cred_ex_id = b98bbfcd-385c-4729-9950-8f52442e475f
Problem report message: Error processing received credential. Error: Invalid structure. Caused by: Issuer is sending incorrect data.
    future.result()
  File "/usr/local/lib/python3.9/asyncio/futures.py", line 201, in result
    raise self._exception
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
Credential: state = done, cred_ex_id = b98bbfcd-385c-4729-9950-8f52442e475f
  File "/home/vscode/.local/lib/python3.9/site-packages/anoncreds/types.py", line 292, in process
    bindings.process_credential(
  File "/home/vscode/.local/lib/python3.9/site-packages/anoncreds/bindings.py", line 715, in process_credential
    do_call(
  File "/home/vscode/.local/lib/python3.9/site-packages/anoncreds/bindings.py", line 504, in do_call
    raise get_current_error(True)
anoncreds.error.AnoncredsError: Error: Invalid structure
Caused by: Issuer is sending incorrect data


The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/protocols/issue_credential/v2_0/handlers/cred_issue_handler.py", line 71, in handle
    cred_ex_record = await cred_manager.store_credential(cred_ex_record)
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/protocols/issue_credential/v2_0/manager.py", line 623, in store_credential
    await cred_format.handler(self.profile).store_credential(
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/protocols/issue_credential/v2_0/formats/indy/handler.py", line 435, in store_credential
    raise e
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/protocols/issue_credential/v2_0/formats/indy/handler.py", line 415, in store_credential
    cred_id_stored = await holder.store_credential(
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/anoncreds/holder.py", line 207, in store_credential
    raise AnonCredsHolderError("Error processing received credential") from err
aries_cloudagent.anoncreds.holder.AnonCredsHolderError: Error processing received credential

@dbluhm
Copy link
Member

dbluhm commented Oct 3, 2023

Quick ack from me; I'll take a closer look when I can!

@usingtechnology
Copy link
Contributor Author

And if I do not add 1 to the cred_rev_id...

Most pertinent part of the error:

  File "/home/vscode/.local/lib/python3.9/site-packages/anoncreds/bindings.py", line 504, in do_call
    raise get_current_error(True)
anoncreds.error.AnoncredsError: Revocation status list does not have the index 4

Full trace:


Traceback (most recent call last):
=================
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/anoncreds/revocation.py", line 934, in _create_credential
    credential = await asyncio.get_event_loop().run_in_executor(
  File "/usr/local/lib/python3.9/asyncio/futures.py", line 284, in __await__
    yield self  # This tells Task to wait for completion.
  File "/usr/local/lib/python3.9/asyncio/tasks.py", line 328, in __wakeup
    future.result()
  File "/usr/local/lib/python3.9/asyncio/futures.py", line 201, in result
    raise self._exception
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/anoncreds/revocation.py", line 936, in <lambda>
    lambda: Credential.create(
  File "/home/vscode/.local/lib/python3.9/site-packages/anoncreds/types.py", line 265, in create
    cred = bindings.create_credential(
  File "/home/vscode/.local/lib/python3.9/site-packages/anoncreds/bindings.py", line 680, in create_credential
    do_call(
  File "/home/vscode/.local/lib/python3.9/site-packages/anoncreds/bindings.py", line 504, in do_call
    raise get_current_error(True)
anoncreds.error.AnoncredsError: Revocation status list does not have the index 4

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/local/lib/python3.9/asyncio/tasks.py", line 258, in __step
    result = coro.throw(exc)
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/protocols/issue_credential/v2_0/routes.py", line 1383, in credential_exchange_issue
    (cred_ex_record, cred_issue_message) = await cred_manager.issue_credential(
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/protocols/issue_credential/v2_0/manager.py", line 508, in issue_credential
    await cred_format.handler(self.profile).issue_credential(
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/protocols/issue_credential/v2_0/formats/indy/handler.py", line 333, in issue_credential
    cred_json, cred_rev_id, rev_reg_def_id = await revocation.create_credential(
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/anoncreds/revocation.py", line 949, in _create_credential
aries_cloudagent.anoncreds.revocation.AnonCredsRevocationError: Error creating credential
2023-10-03 16:48:38,158 aries_cloudagent.admin.server ERROR Handler error with exception: Error creating credential
Traceback (most recent call last):
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/anoncreds/revocation.py", line 934, in _create_credential
    credential = await asyncio.get_event_loop().run_in_executor(
  File "/usr/local/lib/python3.9/asyncio/futures.py", line 284, in __await__
    yield self  # This tells Task to wait for completion.
  File "/usr/local/lib/python3.9/asyncio/tasks.py", line 328, in __wakeup
    future.result()
  File "/usr/local/lib/python3.9/asyncio/futures.py", line 201, in result
    raise self._exception
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/anoncreds/revocation.py", line 936, in <lambda>
    lambda: Credential.create(
  File "/home/vscode/.local/lib/python3.9/site-packages/anoncreds/types.py", line 265, in create
    cred = bindings.create_credential(
  File "/home/vscode/.local/lib/python3.9/site-packages/anoncreds/bindings.py", line 680, in create_credential
    do_call(
  File "/home/vscode/.local/lib/python3.9/site-packages/anoncreds/bindings.py", line 504, in do_call
    raise get_current_error(True)
anoncreds.error.AnoncredsError: Revocation status list does not have the index 4

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/admin/server.py", line 173, in ready_middleware
    return await handler(request)
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/admin/server.py", line 210, in debug_middleware
    return await handler(request)
  File "/home/vscode/.local/lib/python3.9/site-packages/aiohttp_apispec/middlewares.py", line 45, in validation_middleware
    return await handler(request)
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/admin/server.py", line 423, in setup_context
    return await task
  File "/usr/local/lib/python3.9/asyncio/futures.py", line 284, in __await__
    yield self  # This tells Task to wait for completion.
  File "/usr/local/lib/python3.9/asyncio/tasks.py", line 328, in __wakeup
    future.result()
  File "/usr/local/lib/python3.9/asyncio/futures.py", line 201, in result
    raise self._exception
  File "/usr/local/lib/python3.9/asyncio/tasks.py", line 258, in __step
    result = coro.throw(exc)
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/protocols/issue_credential/v2_0/routes.py", line 1383, in credential_exchange_issue
    (cred_ex_record, cred_issue_message) = await cred_manager.issue_credential(
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/protocols/issue_credential/v2_0/manager.py", line 508, in issue_credential
    await cred_format.handler(self.profile).issue_credential(
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/protocols/issue_credential/v2_0/formats/indy/handler.py", line 333, in issue_credential
    cred_json, cred_rev_id, rev_reg_def_id = await revocation.create_credential(
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/anoncreds/revocation.py", line 1010, in create_credential
    cred_json, cred_rev_id = await self._create_credential(
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/anoncreds/revocation.py", line 949, in _create_credential
    raise AnonCredsRevocationError("Error creating credential") from err
aries_cloudagent.anoncreds.revocation.AnonCredsRevocationError: Error creating credential
2023-10-03 16:48:38,177 aiohttp.server ERROR Error handling request
Traceback (most recent call last):
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/anoncreds/revocation.py", line 934, in _create_credential
    credential = await asyncio.get_event_loop().run_in_executor(
  File "/usr/local/lib/python3.9/asyncio/futures.py", line 284, in __await__
    yield self  # This tells Task to wait for completion.
  File "/usr/local/lib/python3.9/asyncio/tasks.py", line 328, in __wakeup
    future.result()
  File "/usr/local/lib/python3.9/asyncio/futures.py", line 201, in result
    raise self._exception
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/anoncreds/revocation.py", line 936, in <lambda>
    lambda: Credential.create(
  File "/home/vscode/.local/lib/python3.9/site-packages/anoncreds/types.py", line 265, in create
    cred = bindings.create_credential(
  File "/home/vscode/.local/lib/python3.9/site-packages/anoncreds/bindings.py", line 680, in create_credential
    do_call(
  File "/home/vscode/.local/lib/python3.9/site-packages/anoncreds/bindings.py", line 504, in do_call
    raise get_current_error(True)
anoncreds.error.AnoncredsError: Revocation status list does not have the index 4

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/vscode/.local/lib/python3.9/site-packages/aiohttp/web_protocol.py", line 433, in _handle_request
    resp = await request_handler(request)
  File "/home/vscode/.local/lib/python3.9/site-packages/aiohttp/web_app.py", line 504, in _handle
    resp = await handler(request)
  File "/home/vscode/.local/lib/python3.9/site-packages/aiohttp/web_middlewares.py", line 117, in impl
    return await handler(request)
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/admin/server.py", line 173, in ready_middleware
    return await handler(request)
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/admin/server.py", line 210, in debug_middleware
    return await handler(request)
  File "/home/vscode/.local/lib/python3.9/site-packages/aiohttp_apispec/middlewares.py", line 45, in validation_middleware
    return await handler(request)
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/admin/server.py", line 423, in setup_context
    return await task
  File "/usr/local/lib/python3.9/asyncio/futures.py", line 284, in __await__
    yield self  # This tells Task to wait for completion.
  File "/usr/local/lib/python3.9/asyncio/tasks.py", line 328, in __wakeup
    future.result()
  File "/usr/local/lib/python3.9/asyncio/futures.py", line 201, in result
    raise self._exception
  File "/usr/local/lib/python3.9/asyncio/tasks.py", line 258, in __step
    result = coro.throw(exc)
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/protocols/issue_credential/v2_0/routes.py", line 1383, in credential_exchange_issue
    (cred_ex_record, cred_issue_message) = await cred_manager.issue_credential(
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/protocols/issue_credential/v2_0/manager.py", line 508, in issue_credential
    await cred_format.handler(self.profile).issue_credential(
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/protocols/issue_credential/v2_0/formats/indy/handler.py", line 333, in issue_credential
    cred_json, cred_rev_id, rev_reg_def_id = await revocation.create_credential(
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/anoncreds/revocation.py", line 1010, in create_credential
    cred_json, cred_rev_id = await self._create_credential(
  File "/workspaces/aries-cloudagent-python/aries_cloudagent/anoncreds/revocation.py", line 949, in _create_credential
    raise AnonCredsRevocationError("Error creating credential") from err
aries_cloudagent.anoncreds.revocation.AnonCredsRevocationError: Error creating credential

@swcurran
Copy link
Member

swcurran commented Oct 3, 2023

So it is an off-by-1 error? The RevId we’re getting back is 0 based and the update is 1 based? That seems very weird...

@usingtechnology
Copy link
Contributor Author

Every rev list will be missing 1 slot; not a huge deal on larger sets.

I am not quite sure where the logic needs to be updated; it's possible it needs to be changed in the anoncreds Credential.create method. It would be nice if the library knows that it is on the last index to publish an event or something. Or if it has a pre-check method that would indicate how much space is left in the list?

It may be possible that it is a timing issue for the additional steps (upload tails file and register the revocation list), although I tried adding plenty of time (5 seconds) to see if that allowed those tasks to complete.

@dbluhm
Copy link
Member

dbluhm commented Oct 5, 2023

Speaking from memory, I think I once asked @andrewwhitehead why the first index is unused. I remember there being a good reason but I don't recall the details unfortunately. For a time I thought that the generic interface would have to be 0-based and then we'd have to map it to Indy where it was strictly expected to be 1-based. I had logic that performed this mapping and then, while testing, I found it was actually causing issues. I believe the anoncreds library is expecting indexes to be 1-based for most operations but the full revocation status list is of course just a list making it subject to 0-based indexing for us in python.

@andrewwhitehead
Copy link
Member

There's no technical reason why the counting has to start at 1, but that's the convention right now. The entries in the tails file are multiplied by powers of the secret gamma value, and the first usable tails entry is the first power, which is I think why the numbering was started there.

@swcurran
Copy link
Member

swcurran commented Oct 5, 2023

I’m not clear what “it" is that is starting skipping 1. Could someone clarify?

@usingtechnology
Copy link
Contributor Author

Near as I can tell, if I set everything to be zero-based, so pass 0 to the anoncreds library to Credential.create, the credential is created successfully but the HOLDER cannot store the credential.

anoncreds.error.AnoncredsError: Error: Invalid structure
Caused by: Issuer is sending incorrect data

So something... the wallet? the spec? does not like zero-based, so the first credential is created using 1. But everything else is zero-based.

@andrewwhitehead
Copy link
Member

andrewwhitehead commented Oct 5, 2023

I added a couple changes here to verify the revocation index when a credential is created, as zero shouldn't be accepted: hyperledger/anoncreds-clsignatures-rs#24

In indy-credx (using deltas), the indexes are always 1-based. In anoncreds-rs, using status lists, I'm not sure at the moment if the first index is skipped or if it's interpreted as starting at 1.

@swcurran swcurran added the AnonCreds Ledger Agnostic AnonCreds label Oct 17, 2023
@swcurran swcurran merged commit c3005f3 into hyperledger:anoncreds-rs Oct 24, 2023
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
AnonCreds Ledger Agnostic AnonCreds
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants