Skip to content

Commit

Permalink
Merge branch 'main' into feat/didcommv2-proof-of-concept
Browse files Browse the repository at this point in the history
Signed-off-by: Micah Peltier <micah6_8@yahoo.com>
  • Loading branch information
mepeltier committed Jun 28, 2024
2 parents 85a3a52 + 926b3f5 commit a515948
Show file tree
Hide file tree
Showing 58 changed files with 2,082 additions and 850 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/integrationtests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ on:
pull_request:
branches:
- main
types: [opened, synchronize, reopened, ready_for_review]

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand All @@ -19,7 +20,7 @@ defaults:
jobs:
test:
runs-on: ubuntu-latest
if: (github.event_name == 'pull_request' && github.repository == 'hyperledger/aries-cloudagent-python') || (github.event_name != 'pull_request')
if: (github.event_name == 'pull_request' && github.event.pull_request.draft == false && github.repository == 'hyperledger/aries-cloudagent-python') || (github.event_name != 'pull_request')
outputs:
is_release: ${{ steps.check_if_release.outputs.is_release }}
steps:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/sonar-pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
with:
fetch-depth: 0
- name: Download PR number artifact
uses: dawidd6/action-download-artifact@v3
uses: dawidd6/action-download-artifact@v6
with:
workflow: Tests
run_id: ${{ github.event.workflow_run.id }}
Expand All @@ -26,7 +26,7 @@ jobs:
with:
path: ./PR_NUMBER
- name: Download Test Coverage
uses: dawidd6/action-download-artifact@v3
uses: dawidd6/action-download-artifact@v6
with:
workflow: Tests
run_id: ${{ github.event.workflow_run.id }}
Expand Down
11 changes: 2 additions & 9 deletions aries_cloudagent/anoncreds/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,7 @@
from ..config.injection_context import InjectionContext
from ..core.error import BaseError
from ..core.profile import Profile
from .models.anoncreds_cred_def import (
CredDef,
CredDefResult,
GetCredDefResult,
)
from .models.anoncreds_cred_def import CredDef, CredDefResult, GetCredDefResult
from .models.anoncreds_revocation import (
GetRevListResult,
GetRevRegDefResult,
Expand Down Expand Up @@ -59,10 +55,7 @@ def __init__(
Args:
message: Message
obj_id: Object ID
obj: Object
TODO: update this docstring - Anoncreds-break.
obj: Generic Object
"""
super().__init__(message, obj_id, obj, *args, **kwargs)
self._message = message
Expand Down
8 changes: 2 additions & 6 deletions aries_cloudagent/anoncreds/default/did_indy/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,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,
GetCredDefResult,
)
from ...models.anoncreds_cred_def import CredDef, CredDefResult, GetCredDefResult
from ...models.anoncreds_revocation import (
GetRevListResult,
GetRevRegDefResult,
Expand All @@ -32,7 +28,7 @@ def __init__(self):
"""Initialize an instance.
Args:
TODO: update this docstring - Anoncreds-break.
None
"""
self._supported_identifiers_regex = re.compile(r"^did:indy:.*$")
Expand Down
2 changes: 1 addition & 1 deletion aries_cloudagent/anoncreds/default/did_web/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def __init__(self):
"""Initialize an instance.
Args:
TODO: update this docstring - Anoncreds-break.
None
"""
self._supported_identifiers_regex = re.compile(
Expand Down
126 changes: 126 additions & 0 deletions aries_cloudagent/anoncreds/default/legacy_indy/recover.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
"""Recover a revocation registry."""

import hashlib
import logging
import time

import aiohttp
import base58
import indy_vdr
from anoncreds import (
RevocationRegistry,
RevocationRegistryDefinition,
)

from ...models.anoncreds_revocation import RevList

LOGGER = logging.getLogger(__name__)


"""
This module calculates a new ledger accumulator, based on the revocation status
on the ledger vs revocations recorded in the wallet.
The calculated transaction can be written to the ledger to get the ledger back
in sync with the wallet.
This function can be used if there were previous revocation errors (i.e. the
credential revocation was successfully written to the wallet but the ledger write
failed.)
"""


class RevocRecoveryException(Exception):
"""Raise exception generating the recovery transaction."""


async def _check_tails_hash_for_inconsistency(tails_location: str, tails_hash: str):
async with aiohttp.ClientSession() as session:
LOGGER.debug("Tails URL: %s", tails_location)
tails_data_http_response = await session.get(tails_location)
tails_data = await tails_data_http_response.read()
remote_tails_hash = base58.b58encode(
hashlib.sha256(tails_data).digest()
).decode("utf-8")
if remote_tails_hash != tails_hash:
raise RevocRecoveryException(
f"Tails hash mismatch {remote_tails_hash} {tails_hash}"
)
else:
LOGGER.debug(f"Checked tails hash: {tails_hash}")


async def fetch_txns(genesis_txns: str, registry_id: str, issuer_id: str) -> tuple[
dict,
set[int],
]:
"""Fetch tails file and revocation registry information."""

LOGGER.debug(f"Fetch revocation registry def {registry_id} from ledger")
revoc_reg_delta_request = indy_vdr.ledger.build_get_revoc_reg_def_request(
None, registry_id
)

pool = await indy_vdr.open_pool(transactions=genesis_txns)
result = await pool.submit_request(revoc_reg_delta_request)
if not result["data"]:
raise RevocRecoveryException(f"Registry definition not found for {registry_id}")

# Load the anoncreds revocation registry definition
rev_reg_def_raw = result["data"]
rev_reg_def_raw["ver"] = "1.0"
rev_reg_def_raw["issuerId"] = issuer_id
revoc_reg_def = RevocationRegistryDefinition.load(rev_reg_def_raw)

await _check_tails_hash_for_inconsistency(
revoc_reg_def.tails_location, revoc_reg_def.tails_hash
)

LOGGER.debug(f"Fetch revocation registry delta {registry_id} from ledger")
to_timestamp = int(time.time())
revoc_reg_delta_request = indy_vdr.ledger.build_get_revoc_reg_delta_request(
None, registry_id, None, to_timestamp
)
result = await pool.submit_request(revoc_reg_delta_request)
if not result["data"]:
raise RevocRecoveryException("Error fetching delta from ledger")

registry_from_ledger = result["data"]["value"]["accum_to"]
registry_from_ledger["ver"] = "1.0"
revoked = set(result["data"]["value"]["revoked"])
LOGGER.debug("Ledger revoked indexes: %s", revoked)

return registry_from_ledger, revoked


async def generate_ledger_rrrecovery_txn(genesis_txns: str, rev_list: RevList):
"""Generate a new ledger accum entry, using the wallet value if revocations ahead of ledger.""" # noqa: E501

registry_from_ledger, prev_revoked = await fetch_txns(
genesis_txns, rev_list.rev_reg_def_id, rev_list.issuer_id
)

set_revoked = {
index for index, value in enumerate(rev_list.revocation_list) if value == 1
}
mismatch = prev_revoked - set_revoked
if mismatch:
LOGGER.warning(
"Credential index(es) revoked on the ledger, but not in wallet: %s",
mismatch,
)

updates = set_revoked - prev_revoked
if not updates:
LOGGER.debug("No updates to perform")
return {}
else:
LOGGER.debug("New revoked indexes: %s", updates)

# Prepare the transaction to write to the ledger
registry = RevocationRegistry.load(registry_from_ledger)
registry = registry.to_dict()
registry["ver"] = "1.0"
registry["value"]["prevAccum"] = registry_from_ledger["value"]["accum"]
registry["value"]["accum"] = rev_list.current_accumulator
registry["value"]["issued"] = []
registry["value"]["revoked"] = list(updates)
return registry
Loading

0 comments on commit a515948

Please sign in to comment.