Skip to content

Commit

Permalink
Anoncreds - schema endorsement
Browse files Browse the repository at this point in the history
Signed-off-by: jamshale <[email protected]>
  • Loading branch information
jamshale committed Jan 23, 2024
1 parent 5a8748e commit 22e86df
Show file tree
Hide file tree
Showing 16 changed files with 682 additions and 127 deletions.
10 changes: 7 additions & 3 deletions aries_cloudagent/anoncreds/default/did_indy/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from ....config.injection_context import InjectionContext
from ....core.profile import Profile
from ...base import BaseAnonCredsRegistrar, BaseAnonCredsResolver
from ...models.anoncreds_cred_def import (
CredDef,
CredDefResult,
Expand All @@ -13,13 +14,12 @@
from ...models.anoncreds_revocation import (
GetRevListResult,
GetRevRegDefResult,
RevRegDef,
RevRegDefResult,
RevList,
RevListResult,
RevRegDef,
RevRegDefResult,
)
from ...models.anoncreds_schema import AnonCredsSchema, GetSchemaResult, SchemaResult
from ...base import BaseAnonCredsRegistrar, BaseAnonCredsResolver

LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -117,3 +117,7 @@ async def update_revocation_list(
) -> RevListResult:
"""Update a revocation list on the registry."""
raise NotImplementedError()

async def txn_submit(self, profile: Profile, ledger_transaction: str) -> str:
"""Submit a transaction to the ledger."""
raise NotImplementedError()
4 changes: 4 additions & 0 deletions aries_cloudagent/anoncreds/default/did_web/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,7 @@ async def update_revocation_list(
) -> RevListResult:
"""Update a revocation list on the registry."""
raise NotImplementedError()

async def txn_submit(self, profile: Profile, ledger_transaction: str) -> str:
"""Submit a transaction to the ledger."""
raise NotImplementedError()
54 changes: 54 additions & 0 deletions aries_cloudagent/anoncreds/default/legacy_indy/author.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
"""Author specific for indy legacy."""

from typing import Optional

from aiohttp import web

from aries_cloudagent.connections.models.conn_record import ConnRecord
from aries_cloudagent.messaging.models.base import BaseModelError
from aries_cloudagent.protocols.endorse_transaction.v1_0.util import (
get_endorser_connection_id,
)
from aries_cloudagent.storage.error import StorageNotFoundError


async def get_endorser_info(profile, options: Optional[dict] = {}):
"""Gets the endorser did for the current transaction."""
endorser_connection_id = options.get("endorser_connection_id", None)
if not endorser_connection_id:
endorser_connection_id = await get_endorser_connection_id(profile)

if not endorser_connection_id:
raise web.HTTPForbidden(reason="No endorser connection found")

try:
async with profile.session() as session:
connection_record = await ConnRecord.retrieve_by_id(
session, endorser_connection_id
)
endorser_info = await connection_record.metadata_get(
session, "endorser_info"
)
except StorageNotFoundError as err:
raise web.HTTPNotFound(
reason=f"Connection for endorser with id {endorser_connection_id} not found"
) from err
except BaseModelError as err:
raise web.HTTPBadRequest(reason=err.roll_up) from err

if not endorser_info:
raise web.HTTPForbidden(
reason=(
"Endorser Info is not set up in "
"connection metadata for this connection record"
)
)
if "endorser_did" not in endorser_info.keys():
raise web.HTTPForbidden(
reason=(
' "endorser_did" is not set in "endorser_info"'
" in connection metadata for this connection record"
)
)

return endorser_info["endorser_did"], endorser_connection_id
116 changes: 92 additions & 24 deletions aries_cloudagent/anoncreds/default/legacy_indy/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@

from base58 import alphabet

from aries_cloudagent.anoncreds.default.legacy_indy.author import get_endorser_info
from aries_cloudagent.protocols.endorse_transaction.v1_0.manager import (
TransactionManager,
TransactionManagerError,
)
from aries_cloudagent.protocols.endorse_transaction.v1_0.util import is_author_role
from aries_cloudagent.storage.error import StorageError

from ....cache.base import BaseCache
from ....config.injection_context import InjectionContext
from ....core.profile import Profile
Expand Down Expand Up @@ -185,6 +193,7 @@ async def register_schema(
profile: Profile,
schema: AnonCredsSchema,
options: Optional[dict] = None,
outbound_handler: Optional[any] = None,
) -> SchemaResult:
"""Register a schema on the registry."""

Expand All @@ -193,11 +202,7 @@ async def register_schema(
# Assume endorser role on the network, no option for 3rd-party endorser
ledger = profile.inject_or(BaseLedger)
if not ledger:
reason = "No ledger available"
if not profile.settings.get_value("wallet.type"):
# TODO is this warning necessary?
reason += ": missing wallet-type?"
raise AnonCredsRegistrationError(reason)
raise AnonCredsRegistrationError("No ledger available")

# Translate schema into format expected by Indy
LOGGER.debug("Registering schema: %s", schema_id)
Expand All @@ -211,33 +216,82 @@ async def register_schema(
}
LOGGER.debug("schema value: %s", indy_schema)

endorser_did = None
create_transaction = options.get("create_transaction_for_endorser", False)

if is_author_role(profile) or create_transaction:
endorser_did, endorser_connection_id = await get_endorser_info(
profile, options
)

write_ledger = (
True if endorser_did is None and not create_transaction else False
)

# Get either the transaction or the seq_no or the created schema
async with ledger:
try:
seq_no = await shield(
ledger.send_schema_anoncreds(schema_id, indy_schema)
result = await shield(
ledger.send_schema_anoncreds(
schema_id,
indy_schema,
write_ledger=write_ledger,
endorser_did=endorser_did,
)
)
except LedgerObjectAlreadyExistsError as err:
indy_schema = err.obj
schema = AnonCredsSchema(
name=indy_schema["name"],
version=indy_schema["version"],
attr_names=indy_schema["attrNames"],
issuer_id=indy_schema["id"].split(":")[0],
)
raise AnonCredsSchemaAlreadyExists(err.message, err.obj_id, schema)
except (AnonCredsIssuerError, LedgerError) as err:
raise AnonCredsRegistrationError("Failed to register schema") from err

return SchemaResult(
job_id=None,
schema_state=SchemaState(
state=SchemaState.STATE_FINISHED,
schema_id=schema_id,
schema=schema,
),
registration_metadata={},
schema_metadata={"seqNo": seq_no},
)
# Didn't need endorsement, so return schema result
if write_ledger:
return SchemaResult(
job_id=None,
schema_state=SchemaState(
state=SchemaState.STATE_FINISHED,
schema_id=schema_id,
schema=schema,
),
registration_metadata={},
schema_metadata={"seqNo": result},
)

# Need endorsement, so execute transaction flow
meta_data = {
"context": {"schema_id": schema_id, "schema": schema.serialize()},
"processing": {},
}

(schema_id, schema_def) = result
transaction_manager = TransactionManager(profile)
try:
transaction = await transaction_manager.create_record(
messages_attach=schema_def["signed_txn"],
connection_id=endorser_connection_id,
meta_data=meta_data,
)
except StorageError:
raise AnonCredsRegistrationError("Failed to store transaction record")

if profile.settings.get("endorser.auto_request"):
try:
(
transaction,
transaction_request,
) = await transaction_manager.create_request(transaction=transaction)
except (StorageError, TransactionManagerError) as err:
raise AnonCredsRegistrationError(
"Transaction manager failed to create request: " + err.roll_up
) from err

await outbound_handler(
transaction_request, connection_id=endorser_connection_id
)
return {
"sent": {"schema_id": schema_id, "schema": schema_def},
"txn": transaction.serialize(),
}

async def get_credential_definition(
self, profile: Profile, cred_def_id: str
Expand Down Expand Up @@ -768,3 +822,17 @@ async def fix_ledger_entry(
applied_txn = ledger_response["result"]

return (rev_reg_delta, recovery_txn, applied_txn)

async def txn_submit(self, profile: Profile, ledger_transaction: str) -> str:
"""Submit a transaction to the ledger."""
ledger = profile.inject(BaseLedger)

if not ledger:
raise LedgerError("No ledger available")

try:
return await shield(
ledger.txn_submit(ledger_transaction, sign=False, taa_accept=False)
)
except LedgerError as err:
raise AnonCredsRegistrationError(err.roll_up) from err
Loading

0 comments on commit 22e86df

Please sign in to comment.