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

Auto-promote author did to public after endorsing #1607

Merged
merged 8 commits into from
Feb 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 39 additions & 4 deletions aries_cloudagent/config/argparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -1690,6 +1690,17 @@ def add_arguments(self, parser: ArgumentParser):
"agent who will be endorsing transactions."
),
)
parser.add_argument(
"--endorser-endorse-with-did",
type=str,
metavar="<endorser-endorse-with-did>",
env_var="ACAPY_ENDORSER_ENDORSE_WITH_DID",
help=(
"For transaction Endorsers, specify the DID to use to endorse "
"transactions. The default (if not specified) is to use the "
"Endorser's Public DID."
),
)
parser.add_argument(
"--endorser-alias",
type=str,
Expand Down Expand Up @@ -1733,6 +1744,13 @@ def add_arguments(self, parser: ArgumentParser):
" the controller must invoke the endpoints required to create the"
" revocation registry and assign to the cred def.)",
)
parser.add_argument(
"--auto-promote-author-did",
action="store_true",
env_var="ACAPY_PROMOTE-AUTHOR-DID",
help="For Authors, specify whether to automatically promote"
" a DID to the wallet public DID after writing to the ledger.",
)

def get_settings(self, args: Namespace):
"""Extract endorser settings."""
Expand All @@ -1742,6 +1760,7 @@ def get_settings(self, args: Namespace):
settings["endorser.auto_endorse"] = False
settings["endorser.auto_write"] = False
settings["endorser.auto_create_rev_reg"] = False
settings["endorser.auto_promote_author_did"] = False

if args.endorser_protocol_role:
if args.endorser_protocol_role == ENDORSER_AUTHOR:
Expand All @@ -1758,6 +1777,17 @@ def get_settings(self, args: Namespace):
"Authors"
)

if args.endorser_endorse_with_did:
if settings["endorser.endorser"]:
settings[
"endorser.endorser_endorse_with_did"
] = args.endorser_endorse_with_did
else:
raise ArgsParseError(
"Parameter --endorser-endorse-with-did should only be set for "
"transaction Endorsers"
)

if args.endorser_alias:
if settings["endorser.author"]:
settings["endorser.endorser_alias"] = args.endorser_alias
Expand Down Expand Up @@ -1790,7 +1820,6 @@ def get_settings(self, args: Namespace):
if settings["endorser.author"]:
settings["endorser.auto_request"] = True
else:
pass
raise ArgsParseError(
"Parameter --auto-request-endorsement should only be set for "
"transaction Authors"
Expand All @@ -1800,7 +1829,6 @@ def get_settings(self, args: Namespace):
if settings["endorser.endorser"]:
settings["endorser.auto_endorse"] = True
else:
pass
raise ArgsParseError(
"Parameter --auto-endorser-transactions should only be set for "
"transaction Endorsers"
Expand All @@ -1810,7 +1838,6 @@ def get_settings(self, args: Namespace):
if settings["endorser.author"]:
settings["endorser.auto_write"] = True
else:
pass
raise ArgsParseError(
"Parameter --auto-write-transactions should only be set for "
"transaction Authors"
Expand All @@ -1820,12 +1847,20 @@ def get_settings(self, args: Namespace):
if settings["endorser.author"]:
settings["endorser.auto_create_rev_reg"] = True
else:
pass
raise ArgsParseError(
"Parameter --auto-create-revocation-transactions should only be set "
"for transaction Authors"
)

if args.auto_promote_author_did:
if settings["endorser.author"]:
settings["endorser.auto_promote_author_did"] = True
else:
raise ArgsParseError(
"Parameter --auto-promote-author-did should only be set "
"for transaction Authors"
)

return settings


Expand Down
1 change: 1 addition & 0 deletions aries_cloudagent/ledger/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ def taa_digest(self, version: str, text: str):
async def txn_endorse(
self,
request_json: str,
endorse_did: DIDInfo = None,
) -> str:
"""Endorse (sign) the provided transaction."""

Expand Down
6 changes: 4 additions & 2 deletions aries_cloudagent/ledger/indy.py
Original file line number Diff line number Diff line change
Expand Up @@ -291,13 +291,14 @@ async def get_wallet_public_did(self) -> DIDInfo:
async def _endorse(
self,
request_json: str,
endorse_did: DIDInfo = None,
) -> str:
if not self.pool.handle:
raise ClosedPoolError(
f"Cannot endorse request with closed pool '{self.pool.name}'"
)

public_info = await self.get_wallet_public_did()
public_info = endorse_did if endorse_did else await self.get_wallet_public_did()
if not public_info:
raise BadLedgerRequestError(
"Cannot endorse transaction without a public DID"
Expand Down Expand Up @@ -403,9 +404,10 @@ async def _submit(
async def txn_endorse(
self,
request_json: str,
endorse_did: DIDInfo = None,
) -> str:
"""Endorse a (signed) ledger transaction."""
return await self._endorse(request_json)
return await self._endorse(request_json, endorse_did=endorse_did)

async def txn_submit(
self,
Expand Down
3 changes: 2 additions & 1 deletion aries_cloudagent/ledger/indy_vdr.py
Original file line number Diff line number Diff line change
Expand Up @@ -1351,6 +1351,7 @@ async def get_wallet_public_did(self) -> DIDInfo:
async def txn_endorse(
self,
request_json: str,
endorse_did: DIDInfo = None,
) -> str:
"""Endorse (sign) the provided transaction."""
try:
Expand All @@ -1360,7 +1361,7 @@ async def txn_endorse(

async with self.profile.session() as session:
wallet = session.inject(BaseWallet)
sign_did = await wallet.get_public_did()
sign_did = endorse_did if endorse_did else await wallet.get_public_did()
if not sign_did:
raise BadLedgerRequestError(
"Cannot endorse transaction without a public DID"
Expand Down
6 changes: 3 additions & 3 deletions aries_cloudagent/ledger/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
)
from .endpoint_type import EndpointType
from .error import BadLedgerRequestError, LedgerError, LedgerTransactionError
from .util import notify_did_event
from .util import notify_register_did_event


class LedgerModulesResultSchema(OpenAPISchema):
Expand Down Expand Up @@ -316,10 +316,10 @@ async def register_ledger_nym(request: web.BaseRequest):
)
)

meta_data = {"verkey": verkey, "alias": alias, "role": role}
meta_data = {"did": did, "verkey": verkey, "alias": alias, "role": role}
if not create_transaction_for_endorser:
# Notify event
await notify_did_event(context.profile, did, meta_data)
await notify_register_did_event(context.profile, did, meta_data)
return web.json_response({"success": success})
else:
transaction_mgr = TransactionManager(context.profile)
Expand Down
4 changes: 2 additions & 2 deletions aries_cloudagent/ledger/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@

TAA_ACCEPTED_RECORD_TYPE = "taa_accepted"

DID_EVENT_PREFIX = "acapy::DID::"
DID_EVENT_PREFIX = "acapy::REGISTER_DID::"
EVENT_LISTENER_PATTERN = re.compile(f"^{DID_EVENT_PREFIX}(.*)?$")


async def notify_did_event(profile: Profile, did: str, meta_data: dict):
async def notify_register_did_event(profile: Profile, did: str, meta_data: dict):
"""Send notification for a DID post-process event."""
await profile.notify(
DID_EVENT_PREFIX + did,
Expand Down
27 changes: 24 additions & 3 deletions aries_cloudagent/protocols/endorse_transaction/v1_0/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from ....storage.error import StorageError, StorageNotFoundError
from ....transport.inbound.receipt import MessageReceipt
from ....wallet.base import BaseWallet
from ....wallet.util import notify_endorse_did_event

from .messages.cancel_transaction import CancelTransaction
from .messages.endorsed_transaction_response import EndorsedTransactionResponse
Expand Down Expand Up @@ -204,6 +205,7 @@ async def create_endorse_response(
self,
transaction: TransactionRecord,
state: str,
use_endorser_did: str = None,
):
"""
Create a response to endorse a transaction.
Expand Down Expand Up @@ -233,10 +235,22 @@ async def create_endorse_response(
wallet: BaseWallet = session.inject_or(BaseWallet)
if not wallet:
raise StorageError("No wallet available")
endorser_did_info = await wallet.get_public_did()
endorser_did_info = None
override_did = (
use_endorser_did
if use_endorser_did
else session.context.settings.get_value(
"endorser.endorser_endorse_with_did"
)
)
if override_did:
endorser_did_info = await wallet.get_local_did(override_did)
else:
endorser_did_info = await wallet.get_public_did()
if not endorser_did_info:
raise StorageError(
"Transaction cannot be endorsed as there is no Public DID in wallet"
"Transaction cannot be endorsed as there is no Public DID in wallet "
"or Endorser DID specified"
)
endorser_did = endorser_did_info.did
endorser_verkey = endorser_did_info.verkey
Expand All @@ -250,7 +264,9 @@ async def create_endorse_response(
raise LedgerError(reason=reason)

async with ledger:
endorsed_msg = await shield(ledger.txn_endorse(transaction_json))
endorsed_msg = await shield(
ledger.txn_endorse(transaction_json, endorse_did=endorser_did_info)
)

# need to return the endorsed msg or else the ledger will reject the
# eventual transaction write
Expand Down Expand Up @@ -790,6 +806,11 @@ async def endorsed_txn_post_processing(
self._profile, rev_reg_id, meta_data
)

elif ledger_response["result"]["txn"]["type"] == "1":
# write DID to ledger
did = ledger_response["result"]["txn"]["data"]["dest"]
await notify_endorse_did_event(self._profile, did, meta_data)

else:
# TODO unknown ledger transaction type, just ignore for now ...
pass
16 changes: 14 additions & 2 deletions aries_cloudagent/protocols/endorse_transaction/v1_0/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,15 @@ class TranIdMatchInfoSchema(OpenAPISchema):
)


class EndorserDIDInfoSchema(OpenAPISchema):
"""Path parameters and validators for request Endorser DID."""

endorser_did = fields.Str(
description="Endorser DID",
required=False,
)


class AssignTransactionJobsSchema(OpenAPISchema):
"""Assign transaction related jobs to connection record."""

Expand Down Expand Up @@ -289,6 +298,7 @@ async def transaction_create_request(request: web.BaseRequest):
tags=["endorse-transaction"],
summary="For Endorser to endorse a particular transaction record",
)
@querystring_schema(EndorserDIDInfoSchema())
@match_info_schema(TranIdMatchInfoSchema())
@response_schema(TransactionRecordSchema(), 200)
async def endorse_transaction_response(request: web.BaseRequest):
Expand All @@ -305,6 +315,7 @@ async def endorse_transaction_response(request: web.BaseRequest):
outbound_handler = request["outbound_message_router"]

transaction_id = request.match_info["tran_id"]
endorser_did = request.query.get("endorser_did")
try:
async with context.profile.session() as session:
transaction = await TransactionRecord.retrieve_by_id(
Expand All @@ -313,6 +324,7 @@ async def endorse_transaction_response(request: web.BaseRequest):
connection_record = await ConnRecord.retrieve_by_id(
session, transaction.connection_id
)
# provided DID is validated in the TransactionManager

except StorageNotFoundError as err:
raise web.HTTPNotFound(reason=err.roll_up) from err
Expand Down Expand Up @@ -341,6 +353,7 @@ async def endorse_transaction_response(request: web.BaseRequest):
) = await transaction_mgr.create_endorse_response(
transaction=transaction,
state=TransactionRecord.STATE_TRANSACTION_ENDORSED,
use_endorser_did=endorser_did,
)
except (IndyIssuerError, LedgerError) as err:
raise web.HTTPBadRequest(reason=err.roll_up) from err
Expand Down Expand Up @@ -787,11 +800,10 @@ async def on_startup_event(profile: Profile, event: Event):
value = {"endorser_did": endorser_did, "endorser_name": endorser_alias}
await conn_record.metadata_set(session, key="endorser_info", value=value)

except Exception as e:
except Exception:
# log the error, but continue
LOGGER.exception(
"Error accepting endorser invitation/configuring endorser connection: %s",
str(e),
)


Expand Down
Loading