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

Anoncreds schema endorsement #2715

Merged
merged 3 commits into from
Jan 31, 2024
Merged

Conversation

jamshale
Copy link
Contributor

@jamshale jamshale commented Jan 16, 2024

Adds the flow for schema endorsement.

The endorsement flow is triggered by the agent having an author role or by manually setting the create_transaction_for_endorser option request param.

The anoncreds registry submits the transaction based on wallet type, and the post processing (storing the schema in the wallet) is triggered by the transaction manager using a new anoncreds schema event.

The endorsement integration tests are run with anoncreds wallets on the endorser and author roles. Added unit tests mostly on the registry register schema flow.

@jamshale jamshale requested a review from ianco January 16, 2024 23:48
@ianco
Copy link
Contributor

ianco commented Jan 18, 2024

Overall looks good.

I think we need to move where the ledger write actually happens, tho. Right now the transaction manager writes to the ledger (https://github.com/hyperledger/aries-cloudagent-python/blob/main/aries_cloudagent/protocols/endorse_transaction/v1_0/manager.py#L428) and then emits the event that we listen for (https://github.com/hyperledger/aries-cloudagent-python/blob/main/aries_cloudagent/protocols/endorse_transaction/v1_0/manager.py#L526).

For anoncreds, I think the ledger write needs to move into our new (anoncreds) event handler method.

@jamshale
Copy link
Contributor Author

@ianco Ok, thanks. I will look into doing that, and add some unit tests and ping you when I'm finished.

@jamshale jamshale marked this pull request as ready for review January 19, 2024 18:34
@jamshale jamshale changed the title WIP - Anoncreds schema endorsement Anoncreds schema endorsement Jan 19, 2024
@jamshale jamshale requested a review from dbluhm January 22, 2024 16:54
ianco
ianco previously approved these changes Jan 22, 2024
Copy link
Contributor

@ianco ianco left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good!

Copy link
Contributor

@dbluhm dbluhm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Super quick comment, will come back with a more detailed review.

aries_cloudagent/anoncreds/default/did_web/registry.py Outdated Show resolved Hide resolved
@jamshale
Copy link
Contributor Author

The latest commit removes the extending of the registry interface, and instead implements the txn_submit method from within the legacy_indy registry. Author triggered txn_submits in the indy ledger and endorser manager complete_transaction create an instance of the LegacyIndyRegistry to submit the transactions.

This will still end up submitting the transaction from the indy ledger but will make sure that ledger is injected from the anoncreds registry.

One drawback is that because the transaction manager and ledger are imported from the ledger routes module on initialization, importing the LegacyIndyRegistry from the top level caused a circular import exception. To get around this the Registry is only imported when needed during anoncred transaction submit operations.

Copy link
Contributor

@dbluhm dbluhm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for taking so long to look deeper on this PR; I feel bad about making some comments early, requesting changes, and then requesting some more after you made those changes... But I think we're not quite aligned on vision for the endorser support yet.

Happy to discuss these points more.

aries_cloudagent/anoncreds/routes.py Outdated Show resolved Hide resolved
aries_cloudagent/anoncreds/issuer.py Outdated Show resolved Hide resolved
aries_cloudagent/anoncreds/events.py Outdated Show resolved Hide resolved
aries_cloudagent/anoncreds/default/legacy_indy/registry.py Outdated Show resolved Hide resolved
@dbluhm
Copy link
Contributor

dbluhm commented Jan 24, 2024

I fear I'm coming across as harsh but I think there were some mistakes made in the first iteration of endorser support in ACA-Py that really need to be corrected. As it stands, I think we're inheriting a bit too much of those mistakes in this iteration.

ianco
ianco previously approved these changes Jan 24, 2024
Copy link
Contributor

@ianco ianco left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not completely happy with how the endorsed transaction is getting saved ... I don't like the (circular) dependency between the transaction manager and Indy registry, and would prefer the ledger transaction gets saved in the event handler somehow (limits the specific ledger dependencies) but let's accept this PR and then re-visit in the next endorser PR.

@jamshale
Copy link
Contributor Author

I fear I'm coming across as harsh but I think there were some mistakes made in the first iteration of endorser support in ACA-Py that really need to be corrected. As it stands, I think we're inheriting a bit too much of those mistakes in this iteration.

I think that's fair. A lot of this is new to me so I appreciate the feedback. Some of the things you mentioned I had been confused about. I don't think it should take to long.

@jamshale
Copy link
Contributor Author

jamshale commented Jan 25, 2024

I think I'm getting a grip on the old implementation and how we want it to change with anoncreds. This should be way better now.

One thing I noticed is that the GET /schema/{id} endpoint doesn't return the state, so you can't see it's finished though the api even though the record is updated. Not sure if that should be change as another ticket.

I added a state for transaction_requested and I used a random uuid for the job-id. Wasn't sure if this was exactly what we wanted to do.

@ianco
Copy link
Contributor

ianco commented Jan 29, 2024

One thing I noticed is that the GET /schema/{id} endpoint doesn't return the state, so you can't see it's finished though the api even though the record is updated. Not sure if that should be change as another ticket.

Isn't there a ledger transaction id that isn't available until the schema is written to the ledger?

@jamshale
Copy link
Contributor Author

jamshale commented Jan 30, 2024

One thing I noticed is that the GET /schema/{id} endpoint doesn't return the state, so you can't see it's finished though the api even though the record is updated. Not sure if that should be change as another ticket.

Isn't there a ledger transaction id that isn't available until the schema is written to the ledger?

That should still be there, yes. This is just for the anoncreds Result object. It has a state field I am setting to transaction_requested and then finished when it is written to the ledger. You can't ever see the finished state from the current GET api. Only the inner anoncreds object.

@jamshale
Copy link
Contributor Author

jamshale commented Jan 30, 2024

POST /schema

{
  "job_id": "db16fd5f8c094d62ba3d1722dacb2467",
  "schema_state": {
    "state": "transaction_requested",
    "schema_id": "WgWxqztrNooG92RXvxSTWv:2:author-schema:1.1",
    "schema": {
      "issuerId": "WgWxqztrNooG92RXvxSTWv",
      "attrNames": [
        "score"
      ],
      "name": "author-schema",
      "version": "1.1"
    }
  },
  "registration_metadata": {
    "txn": {
      "state": "request_sent",
      "created_at": "2024-01-30T00:08:21.960157Z",
      "updated_at": "2024-01-30T00:08:21.968250Z",
      "trace": false,
      "transaction_id": "7e664eb2-2ed0-460e-8411-b6858aeb2fa2",
      "_type": "https://didcomm.org/sign-attachment/1.0/signature-request",
      "signature_request": [
        {
          "context": "did:sov",
          "method": "add-signature",
          "signature_type": "default",
          "signer_goal_code": "aries.transaction.endorse",
          "author_goal_code": "aries.transaction.ledger.write"
        }
      ],
      "signature_response": [],
      "timing": {
        "expires_time": null
      },
      "formats": [
        {
          "attach_id": "4cef3a8f-b910-4794-9326-6f0a638d683c",
          "format": "dif/endorse-transaction/[email protected]"
        }
      ],
      "messages_attach": [
        {
          "@id": "4cef3a8f-b910-4794-9326-6f0a638d683c",
          "mime-type": "application/json",
          "data": {
            "json": "{\"endorser\": \"6bX4vukUZxxGKm7f5bBkmN\", \"identifier\": \"FB5yHWKaZk59hiKqjJKEHs\", \"operation\": {\"data\": {\"attr_names\": [\"score\"], \"name\": \"author-schema\", \"version\": \"1.1\"}, \"type\": \"101\"}, \"protocolVersion\": 2, \"reqId\": 1706573301954441235, \"signature\": \"5ihP9oXmgg6WRRMmNjHiiiP6W3r3S5xVfJFCru3BUzHSqiV6gkmRhvo3UgDzsTmQHU2Z4zp91hwU3cKHtLsG9xWA\"}"
          }
        }
      ],
      "meta_data": {
        "context": {
          "job_id": "db16fd5f8c094d62ba3d1722dacb2467",
          "schema_id": "WgWxqztrNooG92RXvxSTWv:2:author-schema:1.1"
        }
      },
      "connection_id": "2e64c27e-5c35-4090-87ef-a48e4db3f2ba"
    }
  }
}

GET /schems/{id}

{  
 "schema": {
    "issuerId": "FB5yHWKaZk59hiKqjJKEHs",
    "attrNames": [
      "score"
    ],
    "name": "author-schema",
    "version": "1.1"
  },
  "schema_id": "FB5yHWKaZk59hiKqjJKEHs:2:author-schema:1.1",
  "resolution_metadata": {
    "ledger_id": null
  },
  "schema_metadata": {
    "seqNo": 1234
  }
}

dbluhm
dbluhm previously approved these changes Jan 30, 2024
Copy link
Contributor

@dbluhm dbluhm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few comments but I think this is still a great first set of changes. I'm okay with my comments being ignored in the interest of unblocking this from moving forward!

schema_state=SchemaState(
state=SchemaState.STATE_FINISHED,
state=SchemaState.STATE_TRANSACTION_REQUESTED,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be the generic STATE_WAIT.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 I had second guessed adding a more specific state here. Wait makes sense.

Comment on lines -129 to +145
description="Connection identifier (optional) (this is an example)",
description="""
Connection identifier (optional) (this is an example)
You can set this is you know the endorsers connection id you want to use.
If not specified then the agent will attempt to find an endorser connection.
""",
required=False,
example=UUIDFour.EXAMPLE,
)

create_transaction_for_endorser = fields.Bool(
description="""
Create transaction for endorser (optional, default false).
Use this for agents who don't specify an author role but want to
create a transaction for an endorser to sign.""",
required=False,
example=False,
)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is a good use of options. However, I wonder if the first option might be better handled by having an established default endorser (kind of like how we set our public DID and that persists across calls). And I'm honestly not sure what the second one means; is this perhaps a case where we could simplify the interface by sticking to a reasonable default? In what circumstances would we set this value to True?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. These were from the previous implementation.

I thought endorser_connection_id was so you could use a different endorser. It's not needed and the default endorser connection is found without it. Maybe we can remove it.

The create_transaction_for_endorser is when an agent want's to do a transaction but doesn't have the author role set. I'm not sure if this needs to be supported but the integration tests use them.

I think removing these options if we can should be done later as another smaller PR. I'll leave them for now.

Comment on lines 810 to 815
if self._profile.settings.get("wallet.type") == "askar-anoncreds":
event_bus = self.profile.inject(EventBus)
await event_bus.notify(
self._profile,
SchemaRegistrationFinishedEvent.with_payload(meta_data),
)
else:
await notify_schema_event(self._profile, schema_id, meta_data)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think of just calling AnonCredsIssuer.finish_schema directly?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's a good idea. I was just following the existing pattern here but that would be simpler.

@jamshale
Copy link
Contributor Author

A few comments but I think this is still a great first set of changes. I'm okay with my comments being ignored in the interest of unblocking this from moving forward!

I'll update it. I'd rather address them here before the next PR which will be a lot bigger.

Signed-off-by: jamshale <[email protected]>
Copy link

Quality Gate Passed Quality Gate passed

Kudos, no new issues were introduced!

0 New issues
0 Security Hotspots
No data about Coverage
No data about Duplication

See analysis details on SonarCloud

@jamshale
Copy link
Contributor Author

@dbluhm Addressed the comments now.

@jamshale jamshale merged commit 670db01 into openwallet-foundation:main Jan 31, 2024
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants