From f927b21b31fc9e8a6364cb09c62095c58df2d78c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 11:05:23 -0700 Subject: [PATCH 01/12] chore(deps): Bump uuid-utils from 0.7.0 to 0.8.0 (#3034) Bumps [uuid-utils](https://github.com/aminalaee/uuid-utils) from 0.7.0 to 0.8.0. - [Release notes](https://github.com/aminalaee/uuid-utils/releases) - [Commits](https://github.com/aminalaee/uuid-utils/compare/0.7.0...0.8.0) --- updated-dependencies: - dependency-name: uuid-utils dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 189 +++++++++++++++++++++++++++---------------------- pyproject.toml | 2 +- 2 files changed, 104 insertions(+), 87 deletions(-) diff --git a/poetry.lock b/poetry.lock index a3d9b0b08f..421dff1209 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. [[package]] name = "aiohttp" @@ -1009,6 +1009,8 @@ files = [ {file = "frozendict-2.4.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d13b4310db337f4d2103867c5a05090b22bc4d50ca842093779ef541ea9c9eea"}, {file = "frozendict-2.4.4-cp39-cp39-win_amd64.whl", hash = "sha256:b3b967d5065872e27b06f785a80c0ed0a45d1f7c9b85223da05358e734d858ca"}, {file = "frozendict-2.4.4-cp39-cp39-win_arm64.whl", hash = "sha256:4ae8d05c8d0b6134bfb6bfb369d5fa0c4df21eabb5ca7f645af95fdc6689678e"}, + {file = "frozendict-2.4.4-py311-none-any.whl", hash = "sha256:705efca8d74d3facbb6ace80ab3afdd28eb8a237bfb4063ed89996b024bc443d"}, + {file = "frozendict-2.4.4-py312-none-any.whl", hash = "sha256:d9647563e76adb05b7cde2172403123380871360a114f546b4ae1704510801e5"}, {file = "frozendict-2.4.4.tar.gz", hash = "sha256:3f7c031b26e4ee6a3f786ceb5e3abf1181c4ade92dce1f847da26ea2c96008c7"}, ] @@ -1328,9 +1330,13 @@ files = [ {file = "lxml-5.2.2-cp36-cp36m-win_amd64.whl", hash = "sha256:edcfa83e03370032a489430215c1e7783128808fd3e2e0a3225deee278585196"}, {file = "lxml-5.2.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:28bf95177400066596cdbcfc933312493799382879da504633d16cf60bba735b"}, {file = "lxml-5.2.2-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a745cc98d504d5bd2c19b10c79c61c7c3df9222629f1b6210c0368177589fb8"}, + {file = "lxml-5.2.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b590b39ef90c6b22ec0be925b211298e810b4856909c8ca60d27ffbca6c12e6"}, {file = "lxml-5.2.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b336b0416828022bfd5a2e3083e7f5ba54b96242159f83c7e3eebaec752f1716"}, + {file = "lxml-5.2.2-cp37-cp37m-manylinux_2_28_aarch64.whl", hash = "sha256:c2faf60c583af0d135e853c86ac2735ce178f0e338a3c7f9ae8f622fd2eb788c"}, {file = "lxml-5.2.2-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:4bc6cb140a7a0ad1f7bc37e018d0ed690b7b6520ade518285dc3171f7a117905"}, + {file = "lxml-5.2.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7ff762670cada8e05b32bf1e4dc50b140790909caa8303cfddc4d702b71ea184"}, {file = "lxml-5.2.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:57f0a0bbc9868e10ebe874e9f129d2917750adf008fe7b9c1598c0fbbfdde6a6"}, + {file = "lxml-5.2.2-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:a6d2092797b388342c1bc932077ad232f914351932353e2e8706851c870bca1f"}, {file = "lxml-5.2.2-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:60499fe961b21264e17a471ec296dcbf4365fbea611bf9e303ab69db7159ce61"}, {file = "lxml-5.2.2-cp37-cp37m-win32.whl", hash = "sha256:d9b342c76003c6b9336a80efcc766748a333573abf9350f4094ee46b006ec18f"}, {file = "lxml-5.2.2-cp37-cp37m-win_amd64.whl", hash = "sha256:b16db2770517b8799c79aa80f4053cd6f8b716f21f8aca962725a9565ce3ee40"}, @@ -2265,6 +2271,7 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -2272,8 +2279,16 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -2290,6 +2305,7 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -2297,6 +2313,7 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -2599,94 +2616,94 @@ files = [ [[package]] name = "uuid-utils" -version = "0.7.0" +version = "0.8.0" description = "Drop-in replacement for Python UUID in Rust" optional = false python-versions = ">=3.8" files = [ - {file = "uuid_utils-0.7.0-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:1813869ffbf82ebe5fbe749cf0d5e580c605b0fd65d5e738e44439578280f993"}, - {file = "uuid_utils-0.7.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:afb6d3cea6f8b1d9692a1c5d7a93aa6189f973509ea272f4c070399e88cea36b"}, - {file = "uuid_utils-0.7.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38af087e1804774f563ff5f9f043022274dfce110b721ca272f89c0de4ee44e1"}, - {file = "uuid_utils-0.7.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:183603176b65401492db51a16526360997c91e32bc1ffe20ee527337fc57f634"}, - {file = "uuid_utils-0.7.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cebc0e99853c6c12f42e509c27af6131ef36b29e6f381d53c6d81eb1bd21a5f4"}, - {file = "uuid_utils-0.7.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:49e0a42bd9c3825f10d38dcc49bafe5b6543b6c107e4b614e96abf8a7cd58a6f"}, - {file = "uuid_utils-0.7.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a0f978aa8a51ca05142e4e81767d67de08b35ce7db28bc2e600d0c317472013"}, - {file = "uuid_utils-0.7.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c3d2d02868c73334e84d80a7ad60e6c7506c72c059508e9a38db453e4110a652"}, - {file = "uuid_utils-0.7.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:03f710c032d903f273c720dfc080b68fead1ed543de8ad53c4c8dde64c6edd56"}, - {file = "uuid_utils-0.7.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b60c49becd9ff3844fe6e0e87319df9c84dd65bb86c36ad3514981f64e7a737a"}, - {file = "uuid_utils-0.7.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c7ae618dbe27eb5c681a09bec4554d8da8264130a083657fcb80033bbf1c6114"}, - {file = "uuid_utils-0.7.0-cp310-none-win32.whl", hash = "sha256:fb73e36a209c2b585e878748615c0410d2422908ad86fc12b5ae66fedd7e326d"}, - {file = "uuid_utils-0.7.0-cp310-none-win_amd64.whl", hash = "sha256:8e30075e257184328356436a8a6b0e5a0c2b097c224a1e7f9d98a4c350ae5f21"}, - {file = "uuid_utils-0.7.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:ca41e673b807405c0c5aa97ff8959b80884734b1eb55428c7285de245aa3e101"}, - {file = "uuid_utils-0.7.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:cac7e2cf5b40ef297a998fc3ede146f171f99b18210e1237f01002c7e3fa6b0b"}, - {file = "uuid_utils-0.7.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9bad486bcb3b1bd1f6a6e02d9627c51b993305bd2efd3eb4acd0aff529cd7d43"}, - {file = "uuid_utils-0.7.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bd9d769f85bd24a558e8d1aee93400811e3f734199acc5410617f67b1041e0f4"}, - {file = "uuid_utils-0.7.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5c99930f6d51efd15b6c2feb73b386bffccfc82c535eb7d8229e4fb6467f5c6c"}, - {file = "uuid_utils-0.7.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c68ba81b63e23032beda93eeab084f76f141017a26cb895c65777cf3c6c3474"}, - {file = "uuid_utils-0.7.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdaa67667584aba2096292607e2f2e4485df1d1fb2594b2390227cf18df057f0"}, - {file = "uuid_utils-0.7.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6506fedaacd814b50cb62745b058796612c0ddd818a35a70082ea76f8b484931"}, - {file = "uuid_utils-0.7.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:eaa55deae8fd4e7ff30a31f1661e953d70705efa3b09d0fc33576a8eaa589910"}, - {file = "uuid_utils-0.7.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:0d4e7cd2f45e9a3dd371abb8532c6fcbb9befa1551522336095b02369e9144a9"}, - {file = "uuid_utils-0.7.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d6a35a2205318cff201e76cbc6ad428c58e4d9d9ce9c83fd600c5295538be60e"}, - {file = "uuid_utils-0.7.0-cp311-none-win32.whl", hash = "sha256:a7c82f88158f0693cfbc769536d7c09a7cd3c58b22a1b2a041374db1ba03e2d3"}, - {file = "uuid_utils-0.7.0-cp311-none-win_amd64.whl", hash = "sha256:df8f82270295726d1f7d1e26026c29d33a2b40e6dcf8723cf7f5809909eaf6d6"}, - {file = "uuid_utils-0.7.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:53e5d6703f6a38aa1ba59cf8ac0486ac9a847e816e638cf9d6a2a4da4e9f6247"}, - {file = "uuid_utils-0.7.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:c29183a8baedb39fc89e3d98ed2427d49e97ff3680f6832bffe73568d594970d"}, - {file = "uuid_utils-0.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:253fd6e8962008484e02fd4ff4a77ffbddd3867c0c3c24a6919eb4fefc3a2297"}, - {file = "uuid_utils-0.7.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:de53537159212608eb15d4948d0e0098d2fa2b30d453f93d83fe737f0fd7188b"}, - {file = "uuid_utils-0.7.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:116c4b2ff774ce552324b196a3222302a2e78479a301fdb11c2aa1d294ab0f4d"}, - {file = "uuid_utils-0.7.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2eafb4fe02270e22a3bdb03c2107604cf68589a965667cabb71789beed318497"}, - {file = "uuid_utils-0.7.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6ab7a012a1514e498f3f537852257ad2ec9402d1cc165865108dc6d9496bbd4"}, - {file = "uuid_utils-0.7.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:08d58f7de04f3c43a4da05eece58002f4028a7275775ad5013e010abd51d7238"}, - {file = "uuid_utils-0.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7e349d43a969f696dbc7acd002b64952b71674eaf948043a4c6dd1ab65d7c462"}, - {file = "uuid_utils-0.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:53f4c96e7fd1dab33dd56a885d9cffb5aaf21a9064115743e2cee1ff03cb359b"}, - {file = "uuid_utils-0.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c145629c4e48cda275310955632a8231c031f5e9b2eb93b9ab8a081dc6ab6681"}, - {file = "uuid_utils-0.7.0-cp312-none-win_amd64.whl", hash = "sha256:2ca368440148049475ff94f62d5011c34cd7954fe36247698fc05658d04ad9a1"}, - {file = "uuid_utils-0.7.0-cp38-cp38-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:48ed8e59c6fdcc8f825e9fa58afc7f98ba37f744a401ff28a47e7042a761b373"}, - {file = "uuid_utils-0.7.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:bb2777eb2837fc88aceb09addb45bfc7bc8dd0058d19627867b459dac3101a4b"}, - {file = "uuid_utils-0.7.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:070254d2435e9f187e0e8c0626fc6ed108d308cdec669c6d1493dd117bfbedd1"}, - {file = "uuid_utils-0.7.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:424abbbf7e8bdfe78ab552d838efeb9fd033cfe2208f00aadee2704169a1ebad"}, - {file = "uuid_utils-0.7.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:884a72b5f87f7534b685382221d872058bb743294cdb0f2215056b6cc85350fb"}, - {file = "uuid_utils-0.7.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ab1509e21c74feb68b4a3e309bde8c64a8fce2e4552b79cb14058d6bc17a6129"}, - {file = "uuid_utils-0.7.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e6d70efc5e3449f0be3184a6925d0feb29fe40bdcd24ee2611a9021ee9b2580"}, - {file = "uuid_utils-0.7.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:411e29b3a2de713c4a3f3edc653599fb17ef3f38b6a788fecef62c3f229b7b0e"}, - {file = "uuid_utils-0.7.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:3bf10bd5a898d72f50183718ca18bd61b8830c9134469b4d7b9f73f176f06c9f"}, - {file = "uuid_utils-0.7.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:247af7258004f497ec927fcf463914df5447eb691d7e9c23528280c471d6e830"}, - {file = "uuid_utils-0.7.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:01f7c73860b3cef024f9f57515dae5d52a554c3d2480d8410174ec5b609e20f5"}, - {file = "uuid_utils-0.7.0-cp38-none-win32.whl", hash = "sha256:d90d432c85bb2d9b3d67c8483b1134cf4363a39fa3273b8f05dcfde2bdddfc5d"}, - {file = "uuid_utils-0.7.0-cp38-none-win_amd64.whl", hash = "sha256:d31ebe0e6d5d1210da259de4d04ee31dfd5407296302bc2dfcca941e3e8f7bee"}, - {file = "uuid_utils-0.7.0-cp39-cp39-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:076fe5f6e5295a5d47b240ece6047d25ce15e8a114f60acc51b4025c3b973ed9"}, - {file = "uuid_utils-0.7.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:997f4d4f505391b69373c852662b5fe0af8c17b71fe401fea7687261464b9aa5"}, - {file = "uuid_utils-0.7.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59fc7ce3dddb5694f6ecd427d557a342f44075cdaf836cd99033fd0cc500e592"}, - {file = "uuid_utils-0.7.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:463b98c24c5f6f4d0b46174c1068c19007fe6414c38fbd58d5cb6c8d29cdd1ef"}, - {file = "uuid_utils-0.7.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:65c5d33fd056517d0ab1624168359371b012cc6e3a0fd6029d212d3973032e90"}, - {file = "uuid_utils-0.7.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da47c5c4348a5f88749ac8fd54715bdfa18c1317ebf709121721e9b5fb338c66"}, - {file = "uuid_utils-0.7.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:04f39fd90656770422cc7ec46467c2eb758e19d70c5844770bd67834ebae40ea"}, - {file = "uuid_utils-0.7.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a5817e38d497ae643c68044c5c84153fa47557df1f8c1661c17bd1e26bda1058"}, - {file = "uuid_utils-0.7.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:407c15bbde425bc4df829771ef601260eda8617ac5adc6f1eb924d916674c34f"}, - {file = "uuid_utils-0.7.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:d4ac00e7f3bbb578e20fadf81468f28b63d1b29930192d8285e9d01b2f75f270"}, - {file = "uuid_utils-0.7.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6d937d37b696a2e3346171367a6ecf69519af4f2a5325e8e7f9a7cfb61597387"}, - {file = "uuid_utils-0.7.0-cp39-none-win32.whl", hash = "sha256:a4fd826bc2c260716b53db90b2e4c8a0f752aae053fbfbd1860e6e450bcf6ae9"}, - {file = "uuid_utils-0.7.0-cp39-none-win_amd64.whl", hash = "sha256:c1aa084a1b4842c49526ed1189122a96a8cdd73f66ef4219956279044bf6721f"}, - {file = "uuid_utils-0.7.0-pp38-pypy38_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:15eb3621d24fb6aab7f8e7b315356171795ca0f226ba9c31490fb9c08712c201"}, - {file = "uuid_utils-0.7.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bd0dac47317dcdefafe493428237019582ba8adb91c3ec80e033ee631c173f6d"}, - {file = "uuid_utils-0.7.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7b555e485f17ab1ab0cb963ff48c6404b93dd491aef7f52a8ae8c52f7f51841"}, - {file = "uuid_utils-0.7.0-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e66bddd9a469645ede16f0abde5db4dd1a75bc9628ab0b68cad0b848de8494aa"}, - {file = "uuid_utils-0.7.0-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6ad6957427be8f2e48d2f128b3382b3c8e33b4b26542d757e5957c9593773082"}, - {file = "uuid_utils-0.7.0-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4c753f5b690a481d31f13668a57610a4ee9805d0bd4515ab74a3766bea3b0e66"}, - {file = "uuid_utils-0.7.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e99615eb01550e1f883b5b251a04e8afe053dd30fb6c1af823bd14841bd9290"}, - {file = "uuid_utils-0.7.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:cb241970c10cccd37ecac5b3759276ca499cb5b639b832167f91b0a98383e89d"}, - {file = "uuid_utils-0.7.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:14b672b950e792545fde222cf08f9ba9e30ac69399c2ca34b91d4fa457ce1528"}, - {file = "uuid_utils-0.7.0-pp39-pypy39_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:1229b9849a239714899040f8af9c7b3b7ad790483ac0bdf06982eb03383e7a93"}, - {file = "uuid_utils-0.7.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2b6c56101e5dedf06c81c5f3e3dc9d542feb4a5443b01a100c14eef6ae7e9ec4"}, - {file = "uuid_utils-0.7.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77c7f5e54fad8d761e019122080b14fae9568dd09cbb908f349284efa8f9a792"}, - {file = "uuid_utils-0.7.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2b429a906f0dff1c35d55ca17c5f7fedf3149cb405808b43ba4f3a6d21732c31"}, - {file = "uuid_utils-0.7.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:06608c7d643149dee92ceebc73a84bb736d4394f200ecb794541a79e10bc482d"}, - {file = "uuid_utils-0.7.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:655e505c4e7c321e7f60572fdd594bdfdd96556a9699f697045e3d0b4699f30a"}, - {file = "uuid_utils-0.7.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1e59447b45d5988572e450f43de5546e1d2f6643d2e0137d83b5fdad204fd05"}, - {file = "uuid_utils-0.7.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f3010bdaff5c2a78980849aa6b082e7a0013949c8e4d317934f4aaacf14a2d22"}, - {file = "uuid_utils-0.7.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ec25fadeeb34c41ef95a8b849a3e4dcc39e96eb39367323ba873bc1732d6516a"}, - {file = "uuid_utils-0.7.0.tar.gz", hash = "sha256:015aa22711ffd57c5001c2477c6a40121db2794ae3be181a0bf79eef80e28943"}, + {file = "uuid_utils-0.8.0-cp310-cp310-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:79c5cb8e8edafe018d818b6ae702a1cc58c77177f48a6c52138293c383072a11"}, + {file = "uuid_utils-0.8.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:df9db6fc543854266cd21cc232b6021f49b062be1e1fedce6943ef073f767c9d"}, + {file = "uuid_utils-0.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:235508055a1ecc17fa9e4623d36e70d9d5769b36dbe4fa63939535c4bfddb0d3"}, + {file = "uuid_utils-0.8.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:761bdec7e9dba866ef0ba6e3cf1998566a48929d08f450ee20c8a26cd4d81e75"}, + {file = "uuid_utils-0.8.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f8c11d0bff47b43d556377862877f61d2cb239fdfdcb594a25763a84254de8f3"}, + {file = "uuid_utils-0.8.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d8c84c3f4f43b9242327e955696b7760b153112eafe3e168cefc98513b6c001b"}, + {file = "uuid_utils-0.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d93bf94e643ef57254a2e68fda5ba1019b55841ac96922f3a316d4207390859b"}, + {file = "uuid_utils-0.8.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7f3a3f6f8a35b2d5dd369e1300970424dd4169d6da1c7fe6225047e16dbbc6af"}, + {file = "uuid_utils-0.8.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:752ae76423a77da3eafcce1cd0e0b2065d199245dedb53d06821cfdc772aee21"}, + {file = "uuid_utils-0.8.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:a7bc630afb8e6173b92b900d5648c396bf1c23570f13f9283f846e88f13ddfda"}, + {file = "uuid_utils-0.8.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:6277de886cf525f41b5092091a514c08664a1d50f5103e077afeb9b256287625"}, + {file = "uuid_utils-0.8.0-cp310-none-win32.whl", hash = "sha256:fa5595b8cb49cb950d567e1a4b9e3cc709061cb8bad91102c3331b84a440c82c"}, + {file = "uuid_utils-0.8.0-cp310-none-win_amd64.whl", hash = "sha256:ab65787780ffc66e65590025b7da4876e7434086729e9809dfffcbee8cc865e4"}, + {file = "uuid_utils-0.8.0-cp311-cp311-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:3659dbfbb02e0992fcc8b3e569e8fdaf7c6a9c557641cd759ee0ca0750f43a3c"}, + {file = "uuid_utils-0.8.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4f88d378046712158c6b2bae759a79b9d423d6ef31471e7d1fc479171b948b53"}, + {file = "uuid_utils-0.8.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3d860656a11ad3e12b81dc3529cbba0991188a38b8aac364b02be0bfe0c3d6a"}, + {file = "uuid_utils-0.8.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:248a62fdb3f8ca7b6b16978c92e1923252ed3910040154cfdbb891460aa4dc90"}, + {file = "uuid_utils-0.8.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:49993e9a0157ecfc3751785461048515ff5fed8cd2e6fa74c91c469157f9a79c"}, + {file = "uuid_utils-0.8.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a5d1268fadb2c2d06a44f6394cf251e0237136a59a85cfc957587ae7b5355d1"}, + {file = "uuid_utils-0.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5acda5a1c10a69cfa8fe652bbe916af8b7bbb1eec495e3040f435ecc13f1180b"}, + {file = "uuid_utils-0.8.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:78c17a0d51918ffb4b5f3934ab84a19dc340743da7a2db4257d425328eb35df8"}, + {file = "uuid_utils-0.8.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d30c95a5f50031c9d7e220ce51dd48c7ae8d044414715ad1842c41a35a2b004f"}, + {file = "uuid_utils-0.8.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a6eaa3a03c6d219b79501c096cd06f08a91f9a707a1f380a96acc7f9f1620ba3"}, + {file = "uuid_utils-0.8.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:98dc793004cd69c36e03a0654c0b288719ab0545fbbd59274511e3d25dcf6725"}, + {file = "uuid_utils-0.8.0-cp311-none-win32.whl", hash = "sha256:b9c51ca726721bd9532180edaeea57026fdfeaacaa5a7c72fae61865ffe16fda"}, + {file = "uuid_utils-0.8.0-cp311-none-win_amd64.whl", hash = "sha256:f5fe73a1d6ca1b586881a91178a946c6b63509d705999850102aa3a7dea584bf"}, + {file = "uuid_utils-0.8.0-cp312-cp312-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:9a1fe530c0762ad781470ba20464ebaf15b2263b49b74361798153e9fab4db60"}, + {file = "uuid_utils-0.8.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:7bcd38931b35ffbeb1bb5292be72c74f41a51b2a6023093c7203ded5a257956a"}, + {file = "uuid_utils-0.8.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d29f8fdfcdbc97db39d45df8399161738a5b4fae73b9458bce76d6f927b88499"}, + {file = "uuid_utils-0.8.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:842645f00a4883edca9b53908aad57d9658cabf4837b25e3578eaae5b6935eed"}, + {file = "uuid_utils-0.8.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0860b1f3148d1bffe3321cd7f1fa60c202a852bf6d375f453431c1edc3593612"}, + {file = "uuid_utils-0.8.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d99e4b2e294c71cefa92217c14848b186898493a96e1103e4e54c13827e005ea"}, + {file = "uuid_utils-0.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8c4a7208070251e85df64bc428d464ec46da599b709ec1115692b706d3b8f38"}, + {file = "uuid_utils-0.8.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d9496e77aea6e98bddfee52f72b915c02e91dd2462474eb0ddd47028e3235a0c"}, + {file = "uuid_utils-0.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8028b3604a3493d4df2b1e2fdc0def0678805680ed6a66bf97c3ed84b25524ae"}, + {file = "uuid_utils-0.8.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d0248cedc45b9cf1ebad1e2887a30d209aba21f6e0a41571a1f22597d1349333"}, + {file = "uuid_utils-0.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:989dd47a5e383af9b72fa5d74f23c16276e95f1d4f2bb40240d4bf9e7334741f"}, + {file = "uuid_utils-0.8.0-cp312-none-win_amd64.whl", hash = "sha256:1594b8f22067ca080708e6fca13c94e62285ce03c0977841d9f1e5192b66335e"}, + {file = "uuid_utils-0.8.0-cp38-cp38-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:56b27315d37daf74720f39956c5d77417ee0a7944fdc58b44a9094dd8207b3d6"}, + {file = "uuid_utils-0.8.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:e0f681c5085536cb3d0353aeb945a4fb31c9bb6cfabbd8a13a6d849f47107eb6"}, + {file = "uuid_utils-0.8.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15eeddfe03c6e561fe25f90899b46836999fa6af2c600bab79d03815ea579424"}, + {file = "uuid_utils-0.8.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6ac8eb55dd01b456b94ffb366e7ea763c3f107c33fafae86309b6e293575e2b8"}, + {file = "uuid_utils-0.8.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:689970e152c1b21a4da1d862573a41ae130f2271d8f7606ccb1527bf33931b2d"}, + {file = "uuid_utils-0.8.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d6b6235f57e6d47fe17dcda1a0d8b7cc936b7d0a7ddce6955940add752a6300"}, + {file = "uuid_utils-0.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:83b596f25955d7c7fcaadf7ede28b51bd7f69cf4040038fff241e7c83dede685"}, + {file = "uuid_utils-0.8.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:062d841060d2f466fc1db9221f93fc5b031d1453592118e0e936fd9dddb5c70d"}, + {file = "uuid_utils-0.8.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:ac187ffbc1cd105d056ed901f13b78f0fc9b5cf2d7072103181aacb2f1a0d036"}, + {file = "uuid_utils-0.8.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:d54b03d9c9186dff5b24cf93f329180ac4b690274273b4b2b68b8288aaa31dde"}, + {file = "uuid_utils-0.8.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:1295f50a42b230de1bc5abbf5a35bfd2e7e52b3952081e6bc5cdbb21697cd10e"}, + {file = "uuid_utils-0.8.0-cp38-none-win32.whl", hash = "sha256:73ac2e8ec22fca96f2150e92ae657e115b14d9328326835b560cef02b04e737a"}, + {file = "uuid_utils-0.8.0-cp38-none-win_amd64.whl", hash = "sha256:17509f604299da096dfadac58b99844d53ba99a1564a3f0527a8eb040e583661"}, + {file = "uuid_utils-0.8.0-cp39-cp39-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:16ed8988aac8ac52e934dcd1dac5992f4f6ef530469c30b7571adcc203848deb"}, + {file = "uuid_utils-0.8.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:73638f2b70d3d00470c034da2268f86b261d61c4b99256b536c373d7defca744"}, + {file = "uuid_utils-0.8.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9ba9086cff89196017218edc9156fe8b1b9cc22714b37862860aba6f48fa7e1d"}, + {file = "uuid_utils-0.8.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:894ab37a18e12dfb703079373606e3068d5be97b8bce8658d2505087b5f5db09"}, + {file = "uuid_utils-0.8.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d40646f7152d57028e2c807911bdea898a1e2f110859502f31fe8f8ccb954586"}, + {file = "uuid_utils-0.8.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8b6b360edea234a0de1a892e7a96f4189b14619a9389c338a83a14185d0e2f67"}, + {file = "uuid_utils-0.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c09788d5ea000836199033075930108ec417c71f3a7c141ede349b7a831f6287"}, + {file = "uuid_utils-0.8.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4ce326b04bf712d3ad734339b3573470a4fda2474065222dad08528ba3f3ad0b"}, + {file = "uuid_utils-0.8.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d2610935ca6681e26faa1045ecafc0d5ee22f525eed0f993e71dcf9b5bb703f3"}, + {file = "uuid_utils-0.8.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:d665faa544349571a1bb158592a9527c3d7ec17d4baf1de2ef4518d43e04f0e6"}, + {file = "uuid_utils-0.8.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d37791159173b9e63f6cbbce5470bbef129b28504f176f433e2435504854d06d"}, + {file = "uuid_utils-0.8.0-cp39-none-win32.whl", hash = "sha256:536620e5eb89ef4a75c78e7f60fa28321c06af371310e3f25d27e6930bd81ca2"}, + {file = "uuid_utils-0.8.0-cp39-none-win_amd64.whl", hash = "sha256:516f4e63efdacc1e6fea07cc7e2cb2e98579a56bba24d2d32cb50cf8a3ff82d3"}, + {file = "uuid_utils-0.8.0-pp38-pypy38_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:0859c5b907445d8304baf381b3985f72fba366597eed9315cd0ae6d21998d8e0"}, + {file = "uuid_utils-0.8.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:d8544f800e513aa9bf9c9a9df56a218a8a050ffd109ec7a58f86c5decb7e40fa"}, + {file = "uuid_utils-0.8.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dfde725effb4b09ed871a3685bd4bcbacda99a612e43ef65c9fc33dc07c5270c"}, + {file = "uuid_utils-0.8.0-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:59fc6ba8bcd653af28e805c65b7d7e623000bafdfcbbd2f7483556e012d7dbc2"}, + {file = "uuid_utils-0.8.0-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc4d254841950ad33f26ce5fa043a32add0cef5ac96475062d6e23aa76f91d70"}, + {file = "uuid_utils-0.8.0-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd30365435561390db02576ee3a6ff9896a0fc4c5c73dcf3d02a500043776fc4"}, + {file = "uuid_utils-0.8.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62a210eb875e480a2cd843a37719e29853350e87904672fb66b6798eb4d140b7"}, + {file = "uuid_utils-0.8.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:07c9cb3c467ed710c9f3bfbaeb2d2594012a661d42d5e5b63e228ad80d4c4eaf"}, + {file = "uuid_utils-0.8.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:2c414f2cc72e0139f4acff3ab6936a61bc5e37dff42cb66b07948dcd5d646c85"}, + {file = "uuid_utils-0.8.0-pp39-pypy39_pp73-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:91e34a233b0213f9871a2f91c2398794a0a8c08b749936f77c4ddb466402aceb"}, + {file = "uuid_utils-0.8.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ec4e5b9e60d7a602b3e9dcd058fe9ae3d045af02b4cb2d3a125311de7dbc8e8b"}, + {file = "uuid_utils-0.8.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3e2bf7536ea1fc7492b94da7d081c23363047aac167a453df69498fe9bdf5a1"}, + {file = "uuid_utils-0.8.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ea2754b941addb4ef04c958aa4c21d2d6526cd2003d543f9dd6559e5f937a5d6"}, + {file = "uuid_utils-0.8.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cb8049d535f8d8da07ee31842a90543b616fd662afb74680cabdb7cc338e7cc7"}, + {file = "uuid_utils-0.8.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a23ff19249d48c0e0203305348390f12e531f52986a043d095ffc9f9e605cbc"}, + {file = "uuid_utils-0.8.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cadf3de8d588b72a63d91a0b4dac8f0470337f09e94ae7bd2c9a09913f2b886e"}, + {file = "uuid_utils-0.8.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81e76bbd330c45398f42d3f3550d94af3d01a81ff8d95c8f8a07a27e825debb"}, + {file = "uuid_utils-0.8.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c85809d454b3695d70d9695b14c44e7509e3e0fd748d59f7ff8491731c24c9fd"}, + {file = "uuid_utils-0.8.0.tar.gz", hash = "sha256:f9049dd91045bb99bdbe05976faf822d1a6ddb7a4b699ba55eff656750d95ee3"}, ] [[package]] @@ -2867,4 +2884,4 @@ bbs = ["ursa-bbs-signatures"] [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "e23d53b1e134b975a054cd296099b7f00a2c0850941e1ca80fdfb85d60aa1fde" +content-hash = "5aae67738c26befd98f37fea3c5401fcab4dbf6c9c69f1fc5764dbf3518d3df0" diff --git a/pyproject.toml b/pyproject.toml index f2579a2b1f..6545251492 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,7 +47,7 @@ unflatten="~0.1" sd-jwt = "^0.10.3" did-peer-2 = "^0.1.2" did-peer-4 = "^0.1.4" -uuid_utils = "^0.7.0" +uuid_utils = "^0.8.0" # askar aries-askar= { version = "~0.3.0", optional = true } From 61066575f177731ee090665529a2ee9b71701119 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 12:07:12 -0700 Subject: [PATCH 02/12] chore(deps): Bump configargparse from 1.5.5 to 1.7 (#3035) Bumps [configargparse](https://github.com/bw2/ConfigArgParse) from 1.5.5 to 1.7. - [Release notes](https://github.com/bw2/ConfigArgParse/releases) - [Commits](https://github.com/bw2/ConfigArgParse/compare/1.5.5...1.7) --- updated-dependencies: - dependency-name: configargparse dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 10 +++++----- pyproject.toml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/poetry.lock b/poetry.lock index 421dff1209..67d6681add 100644 --- a/poetry.lock +++ b/poetry.lock @@ -551,13 +551,13 @@ files = [ [[package]] name = "configargparse" -version = "1.5.5" +version = "1.7" description = "A drop-in replacement for argparse that allows options to also be set via config files and/or environment variables." optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.5" files = [ - {file = "ConfigArgParse-1.5.5-py3-none-any.whl", hash = "sha256:541360ddc1b15c517f95c0d02d1fca4591266628f3667acdc5d13dccc78884ca"}, - {file = "ConfigArgParse-1.5.5.tar.gz", hash = "sha256:363d80a6d35614bd446e2f2b1b216f3b33741d03ac6d0a92803306f40e555b58"}, + {file = "ConfigArgParse-1.7-py3-none-any.whl", hash = "sha256:d249da6591465c6c26df64a9f73d2536e743be2f244eb3ebe61114af2f94f86b"}, + {file = "ConfigArgParse-1.7.tar.gz", hash = "sha256:e7067471884de5478c58a511e529f0f9bd1c66bfef1dea90935438d6c23306d1"}, ] [package.extras] @@ -2884,4 +2884,4 @@ bbs = ["ursa-bbs-signatures"] [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "5aae67738c26befd98f37fea3c5401fcab4dbf6c9c69f1fc5764dbf3518d3df0" +content-hash = "6d8895caf68777182537454316499ca027668295de7595dad4a6dbc8ba0680a7" diff --git a/pyproject.toml b/pyproject.toml index 6545251492..8414889af7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,7 +22,7 @@ aiohttp-cors="~0.7.0" apispec="^6.6.0" async-timeout="~4.0.2" base58="~2.1.0" -ConfigArgParse="~1.5.3" +ConfigArgParse="~1.7" deepmerge="~0.3.0" ecdsa="~0.19.0" jsonpath-ng="1.6.1" From 21b6ba7685045e19491f75d296b3325e22406fe2 Mon Sep 17 00:00:00 2001 From: jamshale Date: Thu, 13 Jun 2024 18:54:32 +0000 Subject: [PATCH 03/12] Prevent getting stuck with no active registry Signed-off-by: jamshale --- .../v2_0/formats/indy/handler.py | 145 ++++++++++-------- aries_cloudagent/revocation/indy.py | 31 +++- .../models/issuer_rev_reg_record.py | 4 +- 3 files changed, 113 insertions(+), 67 deletions(-) diff --git a/aries_cloudagent/protocols/issue_credential/v2_0/formats/indy/handler.py b/aries_cloudagent/protocols/issue_credential/v2_0/formats/indy/handler.py index 998ae8947d..3b1e01f398 100644 --- a/aries_cloudagent/protocols/issue_credential/v2_0/formats/indy/handler.py +++ b/aries_cloudagent/protocols/issue_credential/v2_0/formats/indy/handler.py @@ -1,19 +1,19 @@ """V2.0 issue-credential indy credential format handler.""" +import asyncio +import json import logging +from typing import Mapping, Optional, Tuple from marshmallow import RAISE -import json -from typing import Mapping, Tuple -import asyncio from ......cache.base import BaseCache from ......core.profile import Profile -from ......indy.issuer import IndyIssuer, IndyIssuerRevocationRegistryFullError from ......indy.holder import IndyHolder, IndyHolderError +from ......indy.issuer import IndyIssuer, IndyIssuerRevocationRegistryFullError from ......indy.models.cred import IndyCredentialSchema -from ......indy.models.cred_request import IndyCredRequestSchema from ......indy.models.cred_abstract import IndyCredAbstractSchema +from ......indy.models.cred_request import IndyCredRequestSchema from ......ledger.base import BaseLedger from ......ledger.multiple_ledger.ledger_requests_executor import ( GET_CRED_DEF, @@ -30,7 +30,6 @@ from ......revocation.models.issuer_cred_rev_record import IssuerCredRevRecord from ......revocation.models.revocation_registry import RevocationRegistry from ......storage.base import BaseStorage - from ...message_types import ( ATTACHMENT_FORMAT, CRED_20_ISSUE, @@ -39,16 +38,14 @@ CRED_20_REQUEST, ) from ...messages.cred_format import V20CredFormat -from ...messages.cred_proposal import V20CredProposal +from ...messages.cred_issue import V20CredIssue from ...messages.cred_offer import V20CredOffer +from ...messages.cred_proposal import V20CredProposal from ...messages.cred_request import V20CredRequest -from ...messages.cred_issue import V20CredIssue from ...models.cred_ex_record import V20CredExRecord from ...models.detail.indy import V20CredExRecordIndy - -from ..handler import CredFormatAttachment, V20CredFormatError, V20CredFormatHandler from ..anoncreds.handler import AnonCredsCredFormatHandler - +from ..handler import CredFormatAttachment, V20CredFormatError, V20CredFormatHandler LOGGER = logging.getLogger(__name__) @@ -369,54 +366,18 @@ async def receive_request( "Indy issue credential format cannot start from credential request" ) - async def issue_credential( - self, cred_ex_record: V20CredExRecord, retries: int = 5 - ) -> CredFormatAttachment: - """Issue indy credential.""" - # Temporary shim while the new anoncreds library integration is in progress - if self.anoncreds_handler: - return await self.anoncreds_handler.issue_credential( - cred_ex_record, retries - ) - - await self._check_uniqueness(cred_ex_record.cred_ex_id) - - cred_offer = cred_ex_record.cred_offer.attachment(IndyCredFormatHandler.format) - cred_request = cred_ex_record.cred_request.attachment( - IndyCredFormatHandler.format - ) - cred_values = cred_ex_record.cred_offer.credential_preview.attr_dict( - decode=False - ) - schema_id = cred_offer["schema_id"] - cred_def_id = cred_offer["cred_def_id"] - - issuer = self.profile.inject(IndyIssuer) - multitenant_mgr = self.profile.inject_or(BaseMultitenantManager) - if multitenant_mgr: - ledger_exec_inst = IndyLedgerRequestsExecutor(self.profile) - else: - ledger_exec_inst = self.profile.inject(IndyLedgerRequestsExecutor) - ledger = ( - await ledger_exec_inst.get_ledger_for_identifier( - schema_id, - txn_record_type=GET_SCHEMA, - ) - )[1] - async with ledger: - schema = await ledger.get_schema(schema_id) - cred_def = await ledger.get_credential_definition(cred_def_id) - revocable = cred_def["value"].get("revocation") - result = None - - for attempt in range(max(retries, 1)): - if attempt > 0: - LOGGER.info( - "Waiting 2s before retrying credential issuance for cred def '%s'", - cred_def_id, - ) - await asyncio.sleep(2) - + async def _issue_credential_retry( + self, + retries: int, + cred_def_id: str, + schema: dict, + cred_offer: dict, + cred_request: dict, + cred_values: dict[str, str], + revocable: bool, + issuer: IndyIssuer, + ) -> tuple[Optional[dict], Optional[str], Optional[str]]: + for _ in range(max(retries, 1)): if revocable: revoc = IndyRevocation(self.profile) registry_info = await revoc.get_or_create_active_registry(cred_def_id) @@ -449,7 +410,71 @@ async def issue_credential( del revoc result = self.get_format_data(CRED_20_ISSUE, json.loads(cred_json)) - break + if result: + return result, rev_reg_id, cred_rev_id + + LOGGER.info( + "Waiting 2s before retrying credential issuance for cred def '%s'", + cred_def_id, + ) + await asyncio.sleep(2) + + return None, None, None + + async def _get_ledger_for_schema(self, schema_id: str): + multitenant_mgr = self.profile.inject_or(BaseMultitenantManager) + if multitenant_mgr: + ledger_exec_inst = IndyLedgerRequestsExecutor(self.profile) + else: + ledger_exec_inst = self.profile.inject(IndyLedgerRequestsExecutor) + return ( + await ledger_exec_inst.get_ledger_for_identifier( + schema_id, + txn_record_type=GET_SCHEMA, + ) + )[1] + + async def issue_credential( + self, cred_ex_record: V20CredExRecord, retries: int = 5 + ) -> CredFormatAttachment: + """Issue indy credential.""" + # Temporary shim while the new anoncreds library integration is in progress + if self.anoncreds_handler: + return await self.anoncreds_handler.issue_credential( + cred_ex_record, retries + ) + + await self._check_uniqueness(cred_ex_record.cred_ex_id) + + cred_offer = cred_ex_record.cred_offer.attachment(IndyCredFormatHandler.format) + cred_request = cred_ex_record.cred_request.attachment( + IndyCredFormatHandler.format + ) + cred_values = cred_ex_record.cred_offer.credential_preview.attr_dict( + decode=False + ) + schema_id = cred_offer["schema_id"] + cred_def_id = cred_offer["cred_def_id"] + + issuer = self.profile.inject(IndyIssuer) + ledger = await self._get_ledger_for_schema(schema_id) + + async with ledger: + schema = await ledger.get_schema(schema_id) + cred_def = await ledger.get_credential_definition(cred_def_id) + + revocable = True if cred_def["value"].get("revocation") else False + + result, rev_reg_id, cred_rev_id = await self._issue_credential_retry( + retries, + cred_def_id, + schema, + cred_offer, + cred_request, + cred_values, + revocable, + issuer, + ) if not result: raise V20CredFormatError( diff --git a/aries_cloudagent/revocation/indy.py b/aries_cloudagent/revocation/indy.py index bd0b8ced36..13a63e0844 100644 --- a/aries_cloudagent/revocation/indy.py +++ b/aries_cloudagent/revocation/indy.py @@ -222,7 +222,7 @@ async def get_issuer_rev_reg_delta( return rev_reg_delta async def get_or_create_active_registry( - self, cred_def_id: str, max_cred_num: int = None + self, cred_def_id: str ) -> Optional[Tuple[IssuerRevRegRecord, RevocationRegistry]]: """Fetch the active revocation registry. @@ -240,14 +240,35 @@ async def get_or_create_active_registry( pass async with self._profile.session() as session: - rev_reg_recs = await IssuerRevRegRecord.query_by_cred_def_id( - session, cred_def_id, {"$neq": IssuerRevRegRecord.STATE_FULL} + rev_reg_records = await IssuerRevRegRecord.query_by_cred_def_id( + session, cred_def_id ) - if not rev_reg_recs: + full_registries = [ + rev + for rev in rev_reg_records + if rev.state == IssuerRevRegRecord.STATE_FULL + ] + + # all registries are full, create a new one + if len(full_registries) == len(rev_reg_records): await self.init_issuer_registry( cred_def_id, - max_cred_num=max_cred_num, + max_cred_num=rev_reg_records[0].max_cred_num, + ) + # if there is a posted registry, activate oldest + else: + posted_registries = sorted( + [ + rev + for rev in rev_reg_records + if rev.state == IssuerRevRegRecord.STATE_POSTED + ] ) + if posted_registries: + await self._set_registry_status( + posted_registries[0].revoc_reg_id, + IssuerRevRegRecord.STATE_ACTIVE, + ) return None async def get_ledger_registry(self, revoc_reg_id: str) -> RevocationRegistry: diff --git a/aries_cloudagent/revocation/models/issuer_rev_reg_record.py b/aries_cloudagent/revocation/models/issuer_rev_reg_record.py index 34e2d53415..973ab41b66 100644 --- a/aries_cloudagent/revocation/models/issuer_rev_reg_record.py +++ b/aries_cloudagent/revocation/models/issuer_rev_reg_record.py @@ -524,7 +524,7 @@ def get_registry(self) -> RevocationRegistry: @classmethod async def query_by_cred_def_id( - cls, session: ProfileSession, cred_def_id: str, state: str = None + cls, session: ProfileSession, cred_def_id: str, state: str = None, limit=None ) -> Sequence["IssuerRevRegRecord"]: """Retrieve issuer revocation registry records by credential definition ID. @@ -539,7 +539,7 @@ async def query_by_cred_def_id( (("cred_def_id", cred_def_id), ("state", state)), ) ) - return await cls.query(session, tag_filter) + return await cls.query(session, tag_filter, limit=limit) @classmethod async def query_by_pending( From a3631848f483c027ec725f50a45c1efdb8563b13 Mon Sep 17 00:00:00 2001 From: jamshale Date: Mon, 17 Jun 2024 19:45:51 +0000 Subject: [PATCH 04/12] Refactor with more efficient queries Signed-off-by: jamshale --- aries_cloudagent/revocation/indy.py | 30 +++++++++---------- .../models/issuer_rev_reg_record.py | 15 ++++++++-- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/aries_cloudagent/revocation/indy.py b/aries_cloudagent/revocation/indy.py index 13a63e0844..3e36f4fac4 100644 --- a/aries_cloudagent/revocation/indy.py +++ b/aries_cloudagent/revocation/indy.py @@ -240,31 +240,31 @@ async def get_or_create_active_registry( pass async with self._profile.session() as session: - rev_reg_records = await IssuerRevRegRecord.query_by_cred_def_id( - session, cred_def_id + full_registries = await IssuerRevRegRecord.query_by_cred_def_id( + session, cred_def_id, None, IssuerRevRegRecord.STATE_FULL, 1 ) - full_registries = [ - rev - for rev in rev_reg_records - if rev.state == IssuerRevRegRecord.STATE_FULL - ] # all registries are full, create a new one - if len(full_registries) == len(rev_reg_records): + if not full_registries: + # Use any registry to get max cred num + any_registry = ( + await IssuerRevRegRecord.query_by_cred_def_id( + session, cred_def_id, limit=1 + ) + )[0] await self.init_issuer_registry( cred_def_id, - max_cred_num=rev_reg_records[0].max_cred_num, + max_cred_num=any_registry.max_cred_num, ) # if there is a posted registry, activate oldest else: - posted_registries = sorted( - [ - rev - for rev in rev_reg_records - if rev.state == IssuerRevRegRecord.STATE_POSTED - ] + posted_registries = await IssuerRevRegRecord.query_by_cred_def_id( + session, cred_def_id, IssuerRevRegRecord.STATE_POSTED, None, None ) if posted_registries: + posted_registries = sorted( + posted_registries, key=lambda r: r.created_at + ) await self._set_registry_status( posted_registries[0].revoc_reg_id, IssuerRevRegRecord.STATE_ACTIVE, diff --git a/aries_cloudagent/revocation/models/issuer_rev_reg_record.py b/aries_cloudagent/revocation/models/issuer_rev_reg_record.py index 973ab41b66..174c950324 100644 --- a/aries_cloudagent/revocation/models/issuer_rev_reg_record.py +++ b/aries_cloudagent/revocation/models/issuer_rev_reg_record.py @@ -524,7 +524,12 @@ def get_registry(self) -> RevocationRegistry: @classmethod async def query_by_cred_def_id( - cls, session: ProfileSession, cred_def_id: str, state: str = None, limit=None + cls, + session: ProfileSession, + cred_def_id: str, + state: str = None, + negative_state: str = None, + limit=None, ) -> Sequence["IssuerRevRegRecord"]: """Retrieve issuer revocation registry records by credential definition ID. @@ -539,7 +544,13 @@ async def query_by_cred_def_id( (("cred_def_id", cred_def_id), ("state", state)), ) ) - return await cls.query(session, tag_filter, limit=limit) + return await cls.query( + session, + tag_filter, + post_filter_positive={"state": state} if state else None, + post_filter_negative={"state": negative_state} if negative_state else None, + limit=limit, + ) @classmethod async def query_by_pending( From f8e82f8ed00e002ae19d3aedae47d0e00cbeabc7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 13:34:33 -0700 Subject: [PATCH 05/12] chore(deps): Bump mkdocs-material from 9.5.10 to 9.5.27 (#3036) Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.10 to 9.5.27. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.10...9.5.27) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- mkdocs-requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mkdocs-requirements.txt b/mkdocs-requirements.txt index a64b578cf6..1ea33417b0 100644 --- a/mkdocs-requirements.txt +++ b/mkdocs-requirements.txt @@ -1,3 +1,3 @@ -mkdocs-material==9.5.10 +mkdocs-material==9.5.27 mike==2.0.0 From c4308a5f7b126f70e31af1e15ece09b25ca7a2fc Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 14:06:52 -0700 Subject: [PATCH 06/12] chore(deps): Bump packaging from 23.1 to 23.2 (#3037) Bumps [packaging](https://github.com/pypa/packaging) from 23.1 to 23.2. - [Release notes](https://github.com/pypa/packaging/releases) - [Changelog](https://github.com/pypa/packaging/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pypa/packaging/compare/23.1...23.2) --- updated-dependencies: - dependency-name: packaging dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 67d6681add..89ef76b8a1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1657,13 +1657,13 @@ files = [ [[package]] name = "packaging" -version = "23.1" +version = "23.2" description = "Core utilities for Python packages" optional = false python-versions = ">=3.7" files = [ - {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, - {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, ] [[package]] @@ -2884,4 +2884,4 @@ bbs = ["ursa-bbs-signatures"] [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "6d8895caf68777182537454316499ca027668295de7595dad4a6dbc8ba0680a7" +content-hash = "91116c343135f25794b717d1afb2870d7f230adea0746df19bb9098c1e995d04" diff --git a/pyproject.toml b/pyproject.toml index 8414889af7..8138372dbc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,7 @@ Markdown="~3.6" markupsafe="2.0.1" marshmallow="~3.20.1" nest_asyncio="~1.6.0" -packaging="~23.1" +packaging="~23.2" portalocker="~2.8.2" prompt_toolkit=">=2.0.9,<2.1.0" pydid="^0.5.1" From 9d39d15ded528c4178cb4eb8ba3412b412c53a48 Mon Sep 17 00:00:00 2001 From: jamshale Date: Mon, 17 Jun 2024 22:15:22 +0000 Subject: [PATCH 07/12] Add unit tests Signed-off-by: jamshale --- aries_cloudagent/revocation/indy.py | 4 +- .../revocation/tests/test_indy.py | 73 ++++++++++++++++++- 2 files changed, 73 insertions(+), 4 deletions(-) diff --git a/aries_cloudagent/revocation/indy.py b/aries_cloudagent/revocation/indy.py index 3e36f4fac4..f22b4fefb3 100644 --- a/aries_cloudagent/revocation/indy.py +++ b/aries_cloudagent/revocation/indy.py @@ -266,8 +266,8 @@ async def get_or_create_active_registry( posted_registries, key=lambda r: r.created_at ) await self._set_registry_status( - posted_registries[0].revoc_reg_id, - IssuerRevRegRecord.STATE_ACTIVE, + revoc_reg_id=posted_registries[0].revoc_reg_id, + state=IssuerRevRegRecord.STATE_ACTIVE, ) return None diff --git a/aries_cloudagent/revocation/tests/test_indy.py b/aries_cloudagent/revocation/tests/test_indy.py index 256b80a04e..43eb0c4b81 100644 --- a/aries_cloudagent/revocation/tests/test_indy.py +++ b/aries_cloudagent/revocation/tests/test_indy.py @@ -1,6 +1,7 @@ -from aries_cloudagent.tests import mock from unittest import IsolatedAsyncioTestCase +from aries_cloudagent.tests import mock + from ...core.in_memory import InMemoryProfile from ...ledger.base import BaseLedger from ...ledger.multiple_ledger.ledger_requests_executor import ( @@ -9,7 +10,6 @@ from ...multitenant.base import BaseMultitenantManager from ...multitenant.manager import MultitenantManager from ...storage.error import StorageNotFoundError - from ..error import ( RevocationNotSupportedError, RevocationRegistryBadSizeError, @@ -255,3 +255,72 @@ async def test_get_ledger_registry(self): mock_from_def.assert_called_once_with( self.ledger.get_revoc_reg_def.return_value, True ) + + @mock.patch( + "aries_cloudagent.revocation.indy.IndyRevocation.get_active_issuer_rev_reg_record", + mock.CoroutineMock( + return_value=mock.MagicMock( + get_registry=mock.MagicMock( + return_value=mock.MagicMock( + get_or_fetch_local_tails_path=mock.CoroutineMock( + return_value="dummy" + ) + ) + ) + ) + ), + ) + async def test_get_or_create_active_registry_has_active_registry(self, *_): + result = await self.revoc.get_or_create_active_registry("cred_def_id") + assert isinstance(result, tuple) + + @mock.patch( + "aries_cloudagent.revocation.indy.IndyRevocation.get_active_issuer_rev_reg_record", + mock.CoroutineMock(side_effect=StorageNotFoundError("No such record")), + ) + @mock.patch( + "aries_cloudagent.revocation.indy.IndyRevocation.init_issuer_registry", + mock.CoroutineMock(return_value=None), + ) + @mock.patch.object( + IssuerRevRegRecord, + "query_by_cred_def_id", + side_effect=[[], [IssuerRevRegRecord(max_cred_num=3)]], + ) + async def test_get_or_create_active_registry_has_no_active_and_only_full_registies( + self, *_ + ): + result = await self.revoc.get_or_create_active_registry("cred_def_id") + + assert not result + assert self.revoc.init_issuer_registry.call_args.kwargs["max_cred_num"] == 3 + + @mock.patch( + "aries_cloudagent.revocation.indy.IndyRevocation.get_active_issuer_rev_reg_record", + mock.CoroutineMock(side_effect=StorageNotFoundError("No such record")), + ) + @mock.patch( + "aries_cloudagent.revocation.indy.IndyRevocation._set_registry_status", + mock.CoroutineMock(return_value=None), + ) + @mock.patch.object( + IssuerRevRegRecord, + "query_by_cred_def_id", + side_effect=[ + [IssuerRevRegRecord(max_cred_num=3)], + [ + IssuerRevRegRecord( + revoc_reg_id="test-rev-reg-id", + state=IssuerRevRegRecord.STATE_POSTED, + ) + ], + ], + ) + async def test_get_or_create_active_registry_has_no_active_with_posted(self, *_): + result = await self.revoc.get_or_create_active_registry("cred_def_id") + + assert not result + assert ( + self.revoc._set_registry_status.call_args.kwargs["state"] + == IssuerRevRegRecord.STATE_ACTIVE + ) From 10f27b1689bcd68e1356ab42348cd7365b64506e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 15:16:15 -0700 Subject: [PATCH 08/12] chore(deps): Bump marshmallow from 3.20.2 to 3.21.3 (#3038) Bumps [marshmallow](https://github.com/marshmallow-code/marshmallow) from 3.20.2 to 3.21.3. - [Changelog](https://github.com/marshmallow-code/marshmallow/blob/dev/CHANGELOG.rst) - [Commits](https://github.com/marshmallow-code/marshmallow/compare/3.20.2...3.21.3) --- updated-dependencies: - dependency-name: marshmallow dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 13 ++++++------- pyproject.toml | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/poetry.lock b/poetry.lock index 89ef76b8a1..eaa5130a3e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1505,22 +1505,21 @@ files = [ [[package]] name = "marshmallow" -version = "3.20.2" +version = "3.21.3" description = "A lightweight library for converting complex datatypes to and from native Python datatypes." optional = false python-versions = ">=3.8" files = [ - {file = "marshmallow-3.20.2-py3-none-any.whl", hash = "sha256:c21d4b98fee747c130e6bc8f45c4b3199ea66bc00c12ee1f639f0aeca034d5e9"}, - {file = "marshmallow-3.20.2.tar.gz", hash = "sha256:4c1daff273513dc5eb24b219a8035559dc573c8f322558ef85f5438ddd1236dd"}, + {file = "marshmallow-3.21.3-py3-none-any.whl", hash = "sha256:86ce7fb914aa865001a4b2092c4c2872d13bc347f3d42673272cabfdbad386f1"}, + {file = "marshmallow-3.21.3.tar.gz", hash = "sha256:4f57c5e050a54d66361e826f94fba213eb10b67b2fdb02c3e0343ce207ba1662"}, ] [package.dependencies] packaging = ">=17.0" [package.extras] -dev = ["pre-commit (>=2.4,<4.0)", "pytest", "pytz", "simplejson", "tox"] -docs = ["alabaster (==0.7.15)", "autodocsumm (==0.2.12)", "sphinx (==7.2.6)", "sphinx-issues (==3.0.1)", "sphinx-version-warning (==1.1.2)"] -lint = ["pre-commit (>=2.4,<4.0)"] +dev = ["marshmallow[tests]", "pre-commit (>=3.5,<4.0)", "tox"] +docs = ["alabaster (==0.7.16)", "autodocsumm (==0.2.12)", "sphinx (==7.3.7)", "sphinx-issues (==4.1.0)", "sphinx-version-warning (==1.1.2)"] tests = ["pytest", "pytz", "simplejson"] [[package]] @@ -2884,4 +2883,4 @@ bbs = ["ursa-bbs-signatures"] [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "91116c343135f25794b717d1afb2870d7f230adea0746df19bb9098c1e995d04" +content-hash = "68ee696d9d85f76bc11c3de934af0469b55417504eeac443ca81bdb5bb9cb0a3" diff --git a/pyproject.toml b/pyproject.toml index 8138372dbc..4b78512b0b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,7 +28,7 @@ ecdsa="~0.19.0" jsonpath-ng="1.6.1" Markdown="~3.6" markupsafe="2.0.1" -marshmallow="~3.20.1" +marshmallow="~3.21.3" nest_asyncio="~1.6.0" packaging="~23.2" portalocker="~2.8.2" From 921a73e2d9b24853248974b6b5b595c73333ba69 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Jun 2024 16:18:53 -0700 Subject: [PATCH 09/12] chore(deps): Bump urllib3 in /demo/playground/examples in the pip group (#3045) Bumps the pip group in /demo/playground/examples with 1 update: [urllib3](https://github.com/urllib3/urllib3). Updates `urllib3` from 2.2.1 to 2.2.2 - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/2.2.1...2.2.2) --- updated-dependencies: - dependency-name: urllib3 dependency-type: indirect dependency-group: pip ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- demo/playground/examples/poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/demo/playground/examples/poetry.lock b/demo/playground/examples/poetry.lock index 276a150f88..20b614400c 100644 --- a/demo/playground/examples/poetry.lock +++ b/demo/playground/examples/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. [[package]] name = "asynctest" @@ -268,13 +268,13 @@ files = [ [[package]] name = "urllib3" -version = "2.2.1" +version = "2.2.2" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.8" files = [ - {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, - {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, + {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, + {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, ] [package.extras] From d5f70e10a9a7cb87030379ada06caa2d47ec8049 Mon Sep 17 00:00:00 2001 From: jamshale <31809382+jamshale@users.noreply.github.com> Date: Mon, 17 Jun 2024 21:30:16 -0700 Subject: [PATCH 10/12] Fix - only run integration tests on opened PR's (#3042) Signed-off-by: jamshale --- .github/workflows/integrationtests.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integrationtests.yml b/.github/workflows/integrationtests.yml index cefa6fc430..9a9b8fc0b8 100644 --- a/.github/workflows/integrationtests.yml +++ b/.github/workflows/integrationtests.yml @@ -7,6 +7,7 @@ on: pull_request: branches: - main + types: [opened, synchronize, reopened, ready_for_review] concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -19,7 +20,7 @@ defaults: jobs: test: runs-on: ubuntu-latest - if: (github.event_name == 'pull_request' && !github.event.pull_request.draft && 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: From cf2d34b0c7ba9b7232d1eda1388d532d69e6f41d Mon Sep 17 00:00:00 2001 From: jamshale <31809382+jamshale@users.noreply.github.com> Date: Mon, 17 Jun 2024 21:35:29 -0700 Subject: [PATCH 11/12] Fix and refactor anoncreds revocation recovery (#3029) * Fix and refactor anoncreds revocation recovery Signed-off-by: jamshale * Add some unit tests Signed-off-by: jamshale * Refactor / Add more unit tests Signed-off-by: jamshale * Add tests / Refactor Signed-off-by: jamshale * Add a couple more unit tests Signed-off-by: jamshale --------- Signed-off-by: jamshale --- .../anoncreds/default/legacy_indy/recover.py | 126 +++++++ .../anoncreds/default/legacy_indy/registry.py | 253 ++++++++----- .../default/legacy_indy/tests/test_recover.py | 190 ++++++++++ .../legacy_indy/tests/test_registry.py | 332 ++++++++++++++++-- aries_cloudagent/anoncreds/revocation.py | 8 +- .../revocation_anoncreds/routes.py | 5 +- 6 files changed, 787 insertions(+), 127 deletions(-) create mode 100644 aries_cloudagent/anoncreds/default/legacy_indy/recover.py create mode 100644 aries_cloudagent/anoncreds/default/legacy_indy/tests/test_recover.py diff --git a/aries_cloudagent/anoncreds/default/legacy_indy/recover.py b/aries_cloudagent/anoncreds/default/legacy_indy/recover.py new file mode 100644 index 0000000000..1933e69763 --- /dev/null +++ b/aries_cloudagent/anoncreds/default/legacy_indy/recover.py @@ -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 diff --git a/aries_cloudagent/anoncreds/default/legacy_indy/registry.py b/aries_cloudagent/anoncreds/default/legacy_indy/registry.py index 582a7ec0c6..21f199454e 100644 --- a/aries_cloudagent/anoncreds/default/legacy_indy/registry.py +++ b/aries_cloudagent/anoncreds/default/legacy_indy/registry.py @@ -1,11 +1,16 @@ """Legacy Indy Registry.""" -import json +import asyncio import logging import re from asyncio import shield from typing import List, Optional, Pattern, Sequence, Tuple +from anoncreds import ( + CredentialDefinition, + RevocationRegistryDefinition, + RevocationRegistryDefinitionPrivate, +) from base58 import alphabet from uuid_utils import uuid4 @@ -13,14 +18,18 @@ from ....cache.base import BaseCache from ....config.injection_context import InjectionContext from ....core.event_bus import EventBus -from ....core.profile import Profile +from ....core.profile import Profile, ProfileSession from ....ledger.base import BaseLedger from ....ledger.error import ( LedgerError, LedgerObjectAlreadyExistsError, LedgerTransactionError, ) -from ....ledger.merkel_validation.constants import GET_SCHEMA +from ....ledger.merkel_validation.constants import ( + GET_REVOC_REG_DELTA, + GET_REVOC_REG_ENTRY, + GET_SCHEMA, +) from ....ledger.multiple_ledger.ledger_requests_executor import ( GET_CRED_DEF, IndyLedgerRequestsExecutor, @@ -33,7 +42,6 @@ ) from ....protocols.endorse_transaction.v1_0.util import is_author_role from ....revocation_anoncreds.models.issuer_cred_rev_record import IssuerCredRevRecord -from ....revocation_anoncreds.recover import generate_ledger_rrrecovery_txn from ....storage.error import StorageError from ....utils import sentinel from ....wallet.did_info import DIDInfo @@ -47,7 +55,7 @@ BaseAnonCredsResolver, ) from ...events import RevListFinishedEvent -from ...issuer import AnonCredsIssuer, AnonCredsIssuerError +from ...issuer import CATEGORY_CRED_DEF, AnonCredsIssuer, AnonCredsIssuerError from ...models.anoncreds_cred_def import ( CredDef, CredDefResult, @@ -72,12 +80,29 @@ SchemaResult, SchemaState, ) +from ...revocation import ( + CATEGORY_REV_LIST, + CATEGORY_REV_REG_DEF, + CATEGORY_REV_REG_DEF_PRIVATE, +) +from .recover import generate_ledger_rrrecovery_txn LOGGER = logging.getLogger(__name__) +# Defaults DEFAULT_CRED_DEF_TAG = "default" DEFAULT_SIGNATURE_TYPE = "CL" +# Common error messages +NO_LEDGER_AVAILABLE_MSG = "No ledger available" +MISSING_WALLET_TYPE_MSG = ": missing wallet-type?" +TRANSACTION_MANAGER_FAILED_MSG = "Transaction manager failed to create request: " +FAILED_TO_STORE_TRANSACTION_RECORD = "Failed to store transaction record" + +# Common settings +ENDORSER_AUTO = "endorser.auto_request" +WALLET_TYPE = "wallet.type" + class LegacyIndyRegistry(BaseAnonCredsResolver, BaseAnonCredsRegistrar): """LegacyIndyRegistry.""" @@ -163,9 +188,9 @@ async def get_schema(self, profile: Profile, schema_id: str) -> GetSchemaResult: ) if not ledger: - reason = "No ledger available" - if not profile.settings.get_value("wallet.type"): - reason += ": missing wallet-type?" + reason = NO_LEDGER_AVAILABLE_MSG + if not profile.settings.get_value(WALLET_TYPE): + reason += MISSING_WALLET_TYPE_MSG raise AnonCredsResolutionError(reason) async with ledger: @@ -207,7 +232,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: - raise AnonCredsRegistrationError("No ledger available") + raise AnonCredsRegistrationError(NO_LEDGER_AVAILABLE_MSG) # Translate schema into format expected by Indy LOGGER.debug("Registering schema: %s", schema_id) @@ -276,9 +301,9 @@ async def register_schema( meta_data=meta_data, ) except StorageError: - raise AnonCredsRegistrationError("Failed to store transaction record") + raise AnonCredsRegistrationError(FAILED_TO_STORE_TRANSACTION_RECORD) - if profile.settings.get("endorser.auto_request"): + if profile.settings.get(ENDORSER_AUTO): try: ( transaction, @@ -286,7 +311,7 @@ async def register_schema( ) = await transaction_manager.create_request(transaction=transaction) except (StorageError, TransactionManagerError) as err: raise AnonCredsRegistrationError( - "Transaction manager failed to create request: " + err.roll_up + TRANSACTION_MANAGER_FAILED_MSG + err.roll_up ) from err responder = profile.inject(BaseResponder) @@ -324,9 +349,9 @@ async def get_credential_definition( txn_record_type=GET_CRED_DEF, ) if not ledger: - reason = "No ledger available" - if not profile.settings.get_value("wallet.type"): - reason += ": missing wallet-type?" + reason = NO_LEDGER_AVAILABLE_MSG + if not profile.settings.get_value(WALLET_TYPE): + reason += MISSING_WALLET_TYPE_MSG raise AnonCredsResolutionError(reason) async with ledger: @@ -367,7 +392,7 @@ async def register_credential_definition( ledger = profile.inject_or(BaseLedger) if not ledger: - raise AnonCredsRegistrationError("No ledger available") + raise AnonCredsRegistrationError(NO_LEDGER_AVAILABLE_MSG) # Check if in wallet but not on ledger issuer = AnonCredsIssuer(profile) @@ -463,9 +488,9 @@ async def register_credential_definition( meta_data=meta_data, ) except StorageError: - raise AnonCredsRegistrationError("Failed to store transaction record") + raise AnonCredsRegistrationError(FAILED_TO_STORE_TRANSACTION_RECORD) - if profile.settings.get("endorser.auto_request"): + if profile.settings.get(ENDORSER_AUTO): try: ( transaction, @@ -473,7 +498,7 @@ async def register_credential_definition( ) = await transaction_manager.create_request(transaction=transaction) except (StorageError, TransactionManagerError) as err: raise AnonCredsRegistrationError( - "Transaction manager failed to create request: " + err.roll_up + TRANSACTION_MANAGER_FAILED_MSG + err.roll_up ) from err responder = profile.inject(BaseResponder) @@ -511,9 +536,9 @@ async def get_revocation_registry_definition( txn_record_type=GET_CRED_DEF, ) if not ledger: - reason = "No ledger available" - if not profile.settings.get_value("wallet.type"): - reason += ": missing wallet-type?" + reason = NO_LEDGER_AVAILABLE_MSG + if not profile.settings.get_value(WALLET_TYPE): + reason += MISSING_WALLET_TYPE_MSG raise AnonCredsResolutionError(reason) async with ledger: @@ -555,7 +580,7 @@ async def register_revocation_registry_definition( ledger = profile.inject(BaseLedger) if not ledger: - raise AnonCredsRegistrationError("No ledger available") + raise AnonCredsRegistrationError(NO_LEDGER_AVAILABLE_MSG) # Translate anoncreds object to indy object indy_rev_reg_def = { @@ -631,9 +656,9 @@ async def register_revocation_registry_definition( meta_data=meta_data, ) except StorageError: - raise AnonCredsRegistrationError("Failed to store transaction record") + raise AnonCredsRegistrationError(FAILED_TO_STORE_TRANSACTION_RECORD) - if profile.settings.get("endorser.auto_request"): + if profile.settings.get(ENDORSER_AUTO): try: ( transaction, @@ -641,7 +666,7 @@ async def register_revocation_registry_definition( ) = await transaction_manager.create_request(transaction=transaction) except (StorageError, TransactionManagerError) as err: raise AnonCredsRegistrationError( - "Transaction manager failed to create request: " + err.roll_up + TRANSACTION_MANAGER_FAILED_MSG + err.roll_up ) from err responder = profile.inject(BaseResponder) @@ -705,9 +730,9 @@ async def _get_ledger(self, profile: Profile, rev_reg_def_id: str): txn_record_type=GET_CRED_DEF, ) if not ledger: - reason = "No ledger available" - if not profile.settings.get_value("wallet.type"): - reason += ": missing wallet-type?" + reason = NO_LEDGER_AVAILABLE_MSG + if not profile.settings.get_value(WALLET_TYPE): + reason += MISSING_WALLET_TYPE_MSG raise AnonCredsResolutionError(reason) return ledger_id, ledger @@ -776,8 +801,15 @@ async def _revoc_reg_entry_with_fix( endorser_did: str = None, ) -> dict: """Send a revocation registry entry to the ledger with fixes if needed.""" - # TODO Handle multitenancy and multi-ledger (like in get cred def) - ledger = profile.inject(BaseLedger) + multitenant_mgr = profile.inject_or(BaseMultitenantManager) + if multitenant_mgr: + ledger_exec_inst = IndyLedgerRequestsExecutor(profile) + else: + ledger_exec_inst = profile.inject(IndyLedgerRequestsExecutor) + _, ledger = await ledger_exec_inst.get_ledger_for_identifier( + rev_list.rev_reg_def_id, + txn_record_type=GET_REVOC_REG_ENTRY, + ) try: async with ledger: @@ -817,7 +849,6 @@ async def _revoc_reg_entry_with_fix( "Ledger update failed due to TAA Issue" ) from err else: - # not sure what happened, raise an error LOGGER.exception("Ledger update failed due to unknown issue") raise AnonCredsRegistrationError( "Ledger update failed due to unknown issue" @@ -892,9 +923,9 @@ async def register_revocation_list( meta_data=meta_data, ) except StorageError: - raise AnonCredsRegistrationError("Failed to store transaction record") + raise AnonCredsRegistrationError(FAILED_TO_STORE_TRANSACTION_RECORD) - if profile.settings.get("endorser.auto_request"): + if profile.settings.get(ENDORSER_AUTO): try: ( transaction, @@ -902,7 +933,7 @@ async def register_revocation_list( ) = await transaction_manager.create_request(transaction=transaction) except (StorageError, TransactionManagerError) as err: raise AnonCredsRegistrationError( - "Transaction manager failed to create request: " + err.roll_up + TRANSACTION_MANAGER_FAILED_MSG + err.roll_up ) from err responder = profile.inject(BaseResponder) @@ -1006,9 +1037,9 @@ async def update_revocation_list( meta_data=meta_data, ) except StorageError: - raise AnonCredsRegistrationError("Failed to store transaction record") + raise AnonCredsRegistrationError(FAILED_TO_STORE_TRANSACTION_RECORD) - if profile.settings.get("endorser.auto_request"): + if profile.settings.get(ENDORSER_AUTO): try: ( transaction, @@ -1016,7 +1047,7 @@ async def update_revocation_list( ) = await transaction_manager.create_request(transaction=transaction) except (StorageError, TransactionManagerError) as err: raise AnonCredsRegistrationError( - "Transaction manager failed to create request: " + err.roll_up + TRANSACTION_MANAGER_FAILED_MSG + err.roll_up ) from err responder = profile.inject(BaseResponder) @@ -1047,64 +1078,56 @@ async def fix_ledger_entry( endorser_did: str = None, ) -> Tuple[dict, dict, dict]: """Fix the ledger entry to match wallet-recorded credentials.""" - # get rev reg delta (revocations published to ledger) - ledger = profile.inject(BaseLedger) + + def _wallet_accumalator_matches_ledger_list( + rev_list: RevList, rev_reg_delta: dict + ) -> bool: + return ( + rev_reg_delta.get("value") + and rev_list.current_accumulator == rev_reg_delta["value"]["accum"] + ) + + applied_txn = {} + recovery_txn = {} + + LOGGER.debug("Fixing ledger entry for revocation list...") + + multitenant_mgr = profile.inject_or(BaseMultitenantManager) + if multitenant_mgr: + ledger_exec_inst = IndyLedgerRequestsExecutor(profile) + else: + ledger_exec_inst = profile.inject(IndyLedgerRequestsExecutor) + _, ledger = await ledger_exec_inst.get_ledger_for_identifier( + rev_list.rev_reg_def_id, + txn_record_type=GET_REVOC_REG_DELTA, + ) + async with ledger: (rev_reg_delta, _) = await ledger.get_revoc_reg_delta( rev_list.rev_reg_def_id ) - # get rev reg records from wallet (revocations and list) - recs = [] - rec_count = 0 - accum_count = 0 - recovery_txn = {} - applied_txn = {} async with profile.session() as session: - recs = await IssuerCredRevRecord.query_by_ids( - session, rev_reg_id=rev_list.rev_reg_def_id - ) - revoked_ids = [] - for rec in recs: - if rec.state == IssuerCredRevRecord.STATE_REVOKED: - revoked_ids.append(int(rec.cred_rev_id)) - if int(rec.cred_rev_id) not in rev_reg_delta["value"]["revoked"]: - # await rec.set_state(session, IssuerCredRevRecord.STATE_ISSUED) - rec_count += 1 + LOGGER.debug(f"revocation_list = {rev_list.revocation_list}") + LOGGER.debug(f"rev_reg_delta = {rev_reg_delta.get('value')}") - LOGGER.debug(">>> fixed entry recs count = %s", rec_count) - LOGGER.debug( - ">>> rev_list.revocation_list: %s", - rev_list.revocation_list, - ) - LOGGER.debug( - '>>> rev_reg_delta.get("value"): %s', rev_reg_delta.get("value") + rev_list = await self._sync_wallet_rev_list_with_issuer_cred_rev_records( + session, rev_list ) - # if we had any revocation discrepancies, check the accumulator value - if rec_count > 0: - if (rev_list.current_accumulator and rev_reg_delta.get("value")) and ( - rev_list.current_accumulator != rev_reg_delta["value"]["accum"] - ): - # self.revoc_reg_entry = rev_reg_delta["value"] - # await self.save(session) - accum_count += 1 - - calculated_txn = await generate_ledger_rrrecovery_txn( - genesis_transactions, - rev_list.rev_reg_def_id, - revoked_ids, + if not _wallet_accumalator_matches_ledger_list(rev_list, rev_reg_delta): + + recovery_txn = await generate_ledger_rrrecovery_txn( + genesis_transactions, rev_list ) - recovery_txn = json.loads(calculated_txn.to_json()) - LOGGER.debug(">>> apply_ledger_update = %s", apply_ledger_update) - if apply_ledger_update: + if apply_ledger_update and recovery_txn: ledger = session.inject_or(BaseLedger) if not ledger: - reason = "No ledger available" - if not session.context.settings.get_value("wallet.type"): - reason += ": missing wallet-type?" + reason = NO_LEDGER_AVAILABLE_MSG + if not session.context.settings.get_value(WALLET_TYPE): + reason += MISSING_WALLET_TYPE_MSG raise LedgerError(reason=reason) async with ledger: @@ -1119,6 +1142,72 @@ async def fix_ledger_entry( return (rev_reg_delta, recovery_txn, applied_txn) + async def _sync_wallet_rev_list_with_issuer_cred_rev_records( + self, session: ProfileSession, rev_list: RevList + ) -> RevList: + """Sync the wallet revocation list with the issuer cred rev records.""" + + async def _revoked_issuer_cred_rev_record_ids() -> List[int]: + cred_rev_records = await IssuerCredRevRecord.query_by_ids( + session, rev_reg_id=rev_list.rev_reg_def_id + ) + return [ + int(rec.cred_rev_id) + for rec in cred_rev_records + if rec.state == "revoked" + ] + + def _revocation_list_to_array_of_indexes( + revocation_list: List[int], + ) -> List[int]: + return [index for index, value in enumerate(revocation_list) if value == 1] + + revoked = await _revoked_issuer_cred_rev_record_ids() + if revoked == _revocation_list_to_array_of_indexes(rev_list.revocation_list): + return rev_list + + # The revocation list is out of sync with the issuer cred rev records + # Recreate the revocation list with the issuer cred rev records + revoc_reg_def_entry = await session.handle.fetch( + CATEGORY_REV_REG_DEF, rev_list.rev_reg_def_id + ) + cred_def_entry = await session.handle.fetch( + CATEGORY_CRED_DEF, + RevRegDef.deserialize(revoc_reg_def_entry.value_json).cred_def_id, + ) + revoc_reg_def_private_entry = await session.handle.fetch( + CATEGORY_REV_REG_DEF_PRIVATE, rev_list.rev_reg_def_id + ) + updated_list = await asyncio.get_event_loop().run_in_executor( + None, + lambda: rev_list.to_native().update( + cred_def=CredentialDefinition.load(cred_def_entry.value_json), + rev_reg_def=RevocationRegistryDefinition.load( + revoc_reg_def_entry.value_json + ), + rev_reg_def_private=RevocationRegistryDefinitionPrivate.load( + revoc_reg_def_private_entry.raw_value + ), + issued=None, + revoked=revoked, + timestamp=None, + ), + ) + rev_list_entry_update = await session.handle.fetch( + CATEGORY_REV_LIST, rev_list.rev_reg_def_id, for_update=True + ) + tags = rev_list_entry_update.tags + rev_list_entry_update = rev_list_entry_update.value_json + rev_list_entry_update["rev_list"] = updated_list.to_dict() + + await session.handle.replace( + CATEGORY_REV_LIST, + rev_list.rev_reg_def_id, + value_json=rev_list_entry_update, + tags=tags, + ) + return RevList.deserialize(updated_list.to_json()) + async def txn_submit( self, ledger: BaseLedger, diff --git a/aries_cloudagent/anoncreds/default/legacy_indy/tests/test_recover.py b/aries_cloudagent/anoncreds/default/legacy_indy/tests/test_recover.py new file mode 100644 index 0000000000..2973c1824b --- /dev/null +++ b/aries_cloudagent/anoncreds/default/legacy_indy/tests/test_recover.py @@ -0,0 +1,190 @@ +"""Test Recover.""" + +import hashlib +from unittest import IsolatedAsyncioTestCase + +import aiohttp +import base58 +import indy_vdr +import pytest +from anoncreds import RevocationRegistryDefinition + +from aries_cloudagent.tests import mock + +from ....models.anoncreds_revocation import RevList, RevRegDef, RevRegDefValue +from ..recover import ( + RevocRecoveryException, + _check_tails_hash_for_inconsistency, + fetch_txns, + generate_ledger_rrrecovery_txn, +) + +GENESIS = '{"reqSignature":{},"txn":{"data":{"data":{"alias":"Node1","blskey":"4N8aUNHSgjQVgkpm8nhNEfDf6txHznoYREg9kirmJrkivgL4oSEimFF6nsQ6M41QvhM2Z33nves5vfSn9n1UwNFJBYtWVnHYMATn76vLuL3zU88KyeAYcHfsih3He6UHcXDxcaecHVz6jhCYz1P2UZn2bDVruL5wXpehgBfBaLKm3Ba","blskey_pop":"RahHYiCvoNCtPTrVtP7nMC5eTYrsUA8WjXbdhNc8debh1agE9bGiJxWBXYNFbnJXoXhWFMvyqhqhRoq737YQemH5ik9oL7R4NTTCz2LEZhkgLJzB3QRQqJyBNyv7acbdHrAT8nQ9UkLbaVL9NBpnWXBTw4LEMePaSHEw66RzPNdAX1","client_ip":"172.17.0.2","client_port":9702,"node_ip":"172.17.0.2","node_port":9701,"services":["VALIDATOR"]},"dest":"Gw6pDLhcBcoQesN72qfotTgFa7cbuqZpkX3Xo6pLhPhv"},"metadata":{"from":"Th7MpTaRZVRYnPiabds81Y"},"type":"0"},"txnMetadata":{"seqNo":1,"txnId":"fea82e10e894419fe2bea7d96296a6d46f50f93f9eeda954ec461b2ed2950b62"},"ver":"1"}\n{"reqSignature":{},"txn":{"data":{"data":{"alias":"Node2","blskey":"37rAPpXVoxzKhz7d9gkUe52XuXryuLXoM6P6LbWDB7LSbG62Lsb33sfG7zqS8TK1MXwuCHj1FKNzVpsnafmqLG1vXN88rt38mNFs9TENzm4QHdBzsvCuoBnPH7rpYYDo9DZNJePaDvRvqJKByCabubJz3XXKbEeshzpz4Ma5QYpJqjk","blskey_pop":"Qr658mWZ2YC8JXGXwMDQTzuZCWF7NK9EwxphGmcBvCh6ybUuLxbG65nsX4JvD4SPNtkJ2w9ug1yLTj6fgmuDg41TgECXjLCij3RMsV8CwewBVgVN67wsA45DFWvqvLtu4rjNnE9JbdFTc1Z4WCPA3Xan44K1HoHAq9EVeaRYs8zoF5","client_ip":"172.17.0.2","client_port":9704,"node_ip":"172.17.0.2","node_port":9703,"services":["VALIDATOR"]},"dest":"8ECVSk179mjsjKRLWiQtssMLgp6EPhWXtaYyStWPSGAb"},"metadata":{"from":"EbP4aYNeTHL6q385GuVpRV"},"type":"0"},"txnMetadata":{"seqNo":2,"txnId":"1ac8aece2a18ced660fef8694b61aac3af08ba875ce3026a160acbc3a3af35fc"},"ver":"1"}\n{"reqSignature":{},"txn":{"data":{"data":{"alias":"Node3","blskey":"3WFpdbg7C5cnLYZwFZevJqhubkFALBfCBBok15GdrKMUhUjGsk3jV6QKj6MZgEubF7oqCafxNdkm7eswgA4sdKTRc82tLGzZBd6vNqU8dupzup6uYUf32KTHTPQbuUM8Yk4QFXjEf2Usu2TJcNkdgpyeUSX42u5LqdDDpNSWUK5deC5","blskey_pop":"QwDeb2CkNSx6r8QC8vGQK3GRv7Yndn84TGNijX8YXHPiagXajyfTjoR87rXUu4G4QLk2cF8NNyqWiYMus1623dELWwx57rLCFqGh7N4ZRbGDRP4fnVcaKg1BcUxQ866Ven4gw8y4N56S5HzxXNBZtLYmhGHvDtk6PFkFwCvxYrNYjh","client_ip":"172.17.0.2","client_port":9706,"node_ip":"172.17.0.2","node_port":9705,"services":["VALIDATOR"]},"dest":"DKVxG2fXXTU8yT5N7hGEbXB3dfdAnYv1JczDUHpmDxya"},"metadata":{"from":"4cU41vWW82ArfxJxHkzXPG"},"type":"0"},"txnMetadata":{"seqNo":3,"txnId":"7e9f355dffa78ed24668f0e0e369fd8c224076571c51e2ea8be5f26479edebe4"},"ver":"1"}\n{"reqSignature":{},"txn":{"data":{"data":{"alias":"Node4","blskey":"2zN3bHM1m4rLz54MJHYSwvqzPchYp8jkHswveCLAEJVcX6Mm1wHQD1SkPYMzUDTZvWvhuE6VNAkK3KxVeEmsanSmvjVkReDeBEMxeDaayjcZjFGPydyey1qxBHmTvAnBKoPydvuTAqx5f7YNNRAdeLmUi99gERUU7TD8KfAa6MpQ9bw","blskey_pop":"RPLagxaR5xdimFzwmzYnz4ZhWtYQEj8iR5ZU53T2gitPCyCHQneUn2Huc4oeLd2B2HzkGnjAff4hWTJT6C7qHYB1Mv2wU5iHHGFWkhnTX9WsEAbunJCV2qcaXScKj4tTfvdDKfLiVuU2av6hbsMztirRze7LvYBkRHV3tGwyCptsrP","client_ip":"172.17.0.2","client_port":9708,"node_ip":"172.17.0.2","node_port":9707,"services":["VALIDATOR"]},"dest":"4PS3EDQ3dW1tci1Bp6543CfuuebjFrg36kLAUcskGfaA"},"metadata":{"from":"TWwCRQRZ2ZHMJFn9TzLp7W"},"type":"0"},"txnMetadata":{"seqNo":4,"txnId":"aa5e817d7cc626170eca175822029339a444eb0ee8f0bd20d3b0b76e566fb008"},"ver":"1"}' + + +rev_reg_def = RevRegDef( + tag="tag", + cred_def_id="CsQY9MGeD3CQP4EyuVFo5m:3:CL:14951:MYCO_Biomarker", + value=RevRegDefValue( + max_cred_num=100, + public_keys={ + "accum_key": {"z": "1 0BB...386"}, + }, + tails_hash="58NNWYnVxVFzAfUztwGSNBL4551XNq6nXk56pCiKJxxt", + tails_location="http://tails-server.com", + ), + issuer_id="CsQY9MGeD3CQP4EyuVFo5m", + type="CL_ACCUM", +) + + +@pytest.mark.anoncreds +class TestLegacyIndyRecover(IsolatedAsyncioTestCase): + + @mock.patch.object( + indy_vdr, + "open_pool", + mock.CoroutineMock( + return_value=mock.MagicMock( + submit_request=mock.CoroutineMock(return_value={"data": {}}) + ) + ), + ) + async def test_fetch_txns_empty_data_from_ledger(self, *_): + with self.assertRaises(RevocRecoveryException): + await fetch_txns( + GENESIS, + "4xE68b6S5VRFrKMMG1U95M:4:4xE68b6S5VRFrKMMG1U95M:3:CL:59232:default:CL_ACCUM:4ae1cc6c-f6bd-486c-8057-88f2ce74e960", + "CsQY9MGeD3CQP4EyuVFo5m", + ) + + @mock.patch.object( + RevocationRegistryDefinition, + "load", + return_value=rev_reg_def.value, + ) + @mock.patch.object( + indy_vdr, + "open_pool", + mock.CoroutineMock( + return_value=mock.MagicMock( + submit_request=mock.CoroutineMock( + return_value={ + "data": { + "ver": "1.0", + "value": { + "accum_to": {}, + "revoked": [1, 0, 1, 0], + }, + } + } + ) + ) + ), + ) + @mock.patch( + "aries_cloudagent.anoncreds.default.legacy_indy.recover._check_tails_hash_for_inconsistency" + ) + async def test_fetch_txns(self, *_): + result = await fetch_txns( + GENESIS, + "4xE68b6S5VRFrKMMG1U95M:4:4xE68b6S5VRFrKMMG1U95M:3:CL:59232:default:CL_ACCUM:4ae1cc6c-f6bd-486c-8057-88f2ce74e960", + "CsQY9MGeD3CQP4EyuVFo5m", + ) + assert isinstance(result, tuple) + + @mock.patch( + "aries_cloudagent.anoncreds.default.legacy_indy.recover.fetch_txns", + mock.CoroutineMock( + return_value=( + { + "ver": "1.0", + "value": { + "accum": "2 124C594B6B20E41B681E92B2C43FD165EA9E68BC3C9D63A82C8893124983CAE94 21 124C5341937827427B0A3A32113BD5E64FB7AB39BD3E5ABDD7970874501CA4897 6 5438CB6F442E2F807812FD9DC0C39AFF4A86B1E6766DBB5359E86A4D70401B0F 4 39D1CA5C4716FFC4FE0853C4FF7F081DFD8DF8D2C2CA79705211680AC77BF3A1 6 70504A5493F89C97C225B68310811A41AD9CD889301F238E93C95AD085E84191 4 39582252194D756D5D86D0EED02BF1B95CE12AED2FA5CD3C53260747D891993C" + }, + }, + {0, 1, 2}, + ) + ), + ) + async def test_generate_ledger_rrrecovery_txn(self): + + # Has updates + result = await generate_ledger_rrrecovery_txn( + GENESIS, + RevList( + issuer_id="CsQY9MGeD3CQP4EyuVFo5m", + current_accumulator="21 124C594B6B20E41B681E92B2C43FD165EA9E68BC3C9D63A82C8893124983CAE94 21 124C5341937827427B0A3A32113BD5E64FB7AB39BD3E5ABDD7970874501CA4897 6 5438CB6F442E2F807812FD9DC0C39AFF4A86B1E6766DBB5359E86A4D70401B0F 4 39D1CA5C4716FFC4FE0853C4FF7F081DFD8DF8D2C2CA79705211680AC77BF3A1 6 70504A5493F89C97C225B68310811A41AD9CD889301F238E93C95AD085E84191 4 39582252194D756D5D86D0EED02BF1B95CE12AED2FA5CD3C53260747D891993C", + revocation_list=[1, 1, 1, 1], + timestamp=1669640864487, + rev_reg_def_id="4xE68b6S5VRFrKMMG1U95M:4:4xE68b6S5VRFrKMMG1U95M:3:CL:59232:default:CL_ACCUM:4ae1cc6c-f6bd-486c-8057-88f2ce74e960", + ), + ) + assert result != {} + # Doesn't have updates + result = await generate_ledger_rrrecovery_txn( + GENESIS, + RevList( + issuer_id="CsQY9MGeD3CQP4EyuVFo5m", + current_accumulator="21 124C594B6B20E41B681E92B2C43FD165EA9E68BC3C9D63A82C8893124983CAE94 21 124C5341937827427B0A3A32113BD5E64FB7AB39BD3E5ABDD7970874501CA4897 6 5438CB6F442E2F807812FD9DC0C39AFF4A86B1E6766DBB5359E86A4D70401B0F 4 39D1CA5C4716FFC4FE0853C4FF7F081DFD8DF8D2C2CA79705211680AC77BF3A1 6 70504A5493F89C97C225B68310811A41AD9CD889301F238E93C95AD085E84191 4 39582252194D756D5D86D0EED02BF1B95CE12AED2FA5CD3C53260747D891993C", + revocation_list=[1, 1, 1, 0], + timestamp=1669640864487, + rev_reg_def_id="4xE68b6S5VRFrKMMG1U95M:4:4xE68b6S5VRFrKMMG1U95M:3:CL:59232:default:CL_ACCUM:4ae1cc6c-f6bd-486c-8057-88f2ce74e960", + ), + ) + assert result == {} + + # Logs waring when ledger has revoked indexes not in wallet + with mock.patch( + "aries_cloudagent.anoncreds.default.legacy_indy.recover.LOGGER" + ) as mock_logger: + result = await generate_ledger_rrrecovery_txn( + GENESIS, + RevList( + issuer_id="CsQY9MGeD3CQP4EyuVFo5m", + current_accumulator="21 124C594B6B20E41B681E92B2C43FD165EA9E68BC3C9D63A82C8893124983CAE94 21 124C5341937827427B0A3A32113BD5E64FB7AB39BD3E5ABDD7970874501CA4897 6 5438CB6F442E2F807812FD9DC0C39AFF4A86B1E6766DBB5359E86A4D70401B0F 4 39D1CA5C4716FFC4FE0853C4FF7F081DFD8DF8D2C2CA79705211680AC77BF3A1 6 70504A5493F89C97C225B68310811A41AD9CD889301F238E93C95AD085E84191 4 39582252194D756D5D86D0EED02BF1B95CE12AED2FA5CD3C53260747D891993C", + revocation_list=[1, 0, 0, 0], + timestamp=1669640864487, + rev_reg_def_id="4xE68b6S5VRFrKMMG1U95M:4:4xE68b6S5VRFrKMMG1U95M:3:CL:59232:default:CL_ACCUM:4ae1cc6c-f6bd-486c-8057-88f2ce74e960", + ), + ) + assert mock_logger.warning.called + assert result == {} + + @mock.patch.object( + aiohttp, + "ClientSession", + mock.MagicMock( + return_value=mock.MagicMock( + get=mock.CoroutineMock( + return_value=mock.MagicMock( + read=mock.CoroutineMock(return_value=b"some data") + ) + ) + ) + ), + ) + @mock.patch.object( + base58, + "b58encode", + side_effect=[ + b"58NNWYnVxVFzAfUztwGSNBL4551XNq6nXk56pCiKJxxt", + b"58NNWYnVxVFzAfUztwGSNBL4551XNq6nXk56pCiKJxxz", + ], + ) + @mock.patch.object( + hashlib, + "sha256", + return_value=mock.MagicMock(digest=mock.MagicMock()), + ) + async def test_check_tails_hash_for_inconsistency(self, *_): + # Matches + await _check_tails_hash_for_inconsistency( + "http://tails-server.com", "58NNWYnVxVFzAfUztwGSNBL4551XNq6nXk56pCiKJxxt" + ) + # Mismatch + with self.assertRaises(RevocRecoveryException): + await _check_tails_hash_for_inconsistency( + "http://tails-server.com", + "58NNWYnVxVFzAfUztwGSNBL4551XNq6nXk56pCiKJxxt", + ) diff --git a/aries_cloudagent/anoncreds/default/legacy_indy/tests/test_registry.py b/aries_cloudagent/anoncreds/default/legacy_indy/tests/test_registry.py index 830a0bb722..4e761fca2d 100644 --- a/aries_cloudagent/anoncreds/default/legacy_indy/tests/test_registry.py +++ b/aries_cloudagent/anoncreds/default/legacy_indy/tests/test_registry.py @@ -5,7 +5,12 @@ from unittest import IsolatedAsyncioTestCase import pytest -from anoncreds import Schema +from anoncreds import ( + CredentialDefinition, + RevocationRegistryDefinition, + RevocationRegistryDefinitionPrivate, + Schema, +) from base58 import alphabet from .....anoncreds.base import ( @@ -18,9 +23,13 @@ ) from .....askar.profile_anon import AskarAnoncredsProfile from .....connections.models.conn_record import ConnRecord -from .....core.in_memory.profile import InMemoryProfile +from .....core.event_bus import EventBus +from .....core.in_memory.profile import InMemoryProfile, InMemoryProfileSession from .....ledger.base import BaseLedger from .....ledger.error import LedgerObjectAlreadyExistsError +from .....ledger.multiple_ledger.ledger_requests_executor import ( + IndyLedgerRequestsExecutor, +) from .....messaging.responder import BaseResponder from .....protocols.endorse_transaction.v1_0.manager import ( TransactionManager, @@ -28,6 +37,7 @@ from .....protocols.endorse_transaction.v1_0.models.transaction_record import ( TransactionRecord, ) +from .....revocation_anoncreds.models.issuer_cred_rev_record import IssuerCredRevRecord from .....tests import mock from ....issuer import AnonCredsIssuer from ....models.anoncreds_cred_def import ( @@ -41,6 +51,7 @@ RevListResult, RevRegDef, RevRegDefResult, + RevRegDefState, RevRegDefValue, ) from .. import registry as test_module @@ -81,6 +92,55 @@ ) +class MockTxn: + def to_json(self): + return json.dumps(self.__dict__) + + +class MockRevRegDefEntry: + def __init__(self, name="name"): + self.name = name + + tags = { + "state": RevRegDefState.STATE_ACTION, + } + value = "mock_value" + value_json = { + "value": { + "maxCredNum": 100, + "publicKeys": {"accumKey": {"z": "1 0BB...386"}}, + "tailsHash": "string", + "tailsLocation": "string", + }, + "credDefId": "CsQY9MGeD3CQP4EyuVFo5m:3:CL:14951:MYCO_Biomarker", + "issuerId": "CsQY9MGeD3CQP4EyuVFo5m", + "revocDefType": "CL_ACCUM", + "tag": "string", + } + + +class MockCredDefEntry: + value_json = {} + + +class MockRevListEntry: + tags = {} + value = "mock_value" + value_json = { + "issuerId": "CsQY9MGeD3CQP4EyuVFo5m", + "revRegDefId": "4xE68b6S5VRFrKMMG1U95M:4:4xE68b6S5VRFrKMMG1U95M:3:CL:59232:default:CL_ACCUM:4ae1cc6c-f6bd-486c-8057-88f2ce74e960", + "revocationList": [0, 1, 0, 0], + "currentAccumulator": "21 124C594B6B20E41B681E92B2C43FD165EA9E68BC3C9D63A82C8893124983CAE94 21 124C5341937827427B0A3A32113BD5E64FB7AB39BD3E5ABDD7970874501CA4897 6 5438CB6F442E2F807812FD9DC0C39AFF4A86B1E6766DBB5359E86A4D70401B0F 4 39D1CA5C4716FFC4FE0853C4FF7F081DFD8DF8D2C2CA79705211680AC77BF3A1 6 70504A5493F89C97C225B68310811A41AD9CD889301F238E93C95AD085E84191 4 39582252194D756D5D86D0EED02BF1B95CE12AED2FA5CD3C53260747D891993C", + "timestamp": 1669640864487, + } + + def to_json(self): + return self.value_json + + def to_dict(self): + return self.value_json + + @pytest.mark.anoncreds class TestLegacyIndyRegistry(IsolatedAsyncioTestCase): async def asyncSetUp(self): @@ -738,11 +798,29 @@ async def test_txn_submit(self): result = await self.registry.txn_submit(ledger, "test_txn") assert result == "transaction_id" - async def test_register_revocation_list_no_endorsement(self): - self.profile.context.injector.bind_instance( - BaseLedger, - mock.MagicMock(send_revoc_reg_entry=mock.CoroutineMock(return_value=1)), + @mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + return_value=( + "id", + mock.MagicMock( + send_revoc_reg_entry=mock.CoroutineMock(return_value="transaction_id") + ), + ), + ) + @mock.patch.object(InMemoryProfileSession, "handle") + async def test_register_revocation_list_no_endorsement( + self, mock_handle, mock_send_revoc_reg_entry + ): + self.profile.inject_or = mock.MagicMock() + mock_handle.fetch = mock.CoroutineMock( + side_effect=[ + mock.CoroutineMock(return_value=None), + mock.CoroutineMock(return_value=None), + mock.CoroutineMock(return_value=None), + ] ) + result = await self.registry.register_revocation_list( self.profile, RevRegDef( @@ -770,9 +848,7 @@ async def test_register_revocation_list_no_endorsement(self): ) assert isinstance(result, RevListResult) - assert self.profile.context.injector.get_provider( - BaseLedger - )._instance.send_revoc_reg_entry.called + assert mock_send_revoc_reg_entry.called @mock.patch.object( ConnRecord, @@ -786,17 +862,28 @@ async def test_register_revocation_list_no_endorsement(self): "create_record", return_value=TransactionRecord(), ) - async def test_register_revocation_list_with_author_role( - self, mock_create_record, mock_endorsement_conn - ): - self.profile.context.injector.bind_instance( - BaseLedger, + @mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + return_value=( + "id", mock.MagicMock( send_revoc_reg_entry=mock.CoroutineMock( - return_value=("id", {"signed_txn": "txn"}) + return_value=( + "rev_reg_def_id", + { + "signed_txn": "txn", + }, + ) ) ), - ) + ), + ) + async def test_register_revocation_list_with_author_role( + self, mock_send_revoc_reg_entry, mock_create_record, _ + ): + + self.profile.inject_or = mock.MagicMock() self.profile.settings.set_value("endorser.author", True) result = await self.registry.register_revocation_list( @@ -828,10 +915,8 @@ async def test_register_revocation_list_with_author_role( ) assert isinstance(result, RevListResult) - assert self.profile.context.injector.get_provider( - BaseLedger - )._instance.send_revoc_reg_entry.called assert mock_create_record.called + assert mock_send_revoc_reg_entry.called @mock.patch.object( ConnRecord, @@ -845,17 +930,27 @@ async def test_register_revocation_list_with_author_role( "create_record", return_value=TransactionRecord(), ) - async def test_register_revocation_list_with_create_transaction_option( - self, mock_create_record, mock_endorsement_conn - ): - self.profile.context.injector.bind_instance( - BaseLedger, + @mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + return_value=( + "id", mock.MagicMock( send_revoc_reg_entry=mock.CoroutineMock( - return_value=("id", {"signed_txn": "txn"}) + return_value=( + "rev_reg_def_id", + { + "signed_txn": "txn", + }, + ) ) ), - ) + ), + ) + async def test_register_revocation_list_with_create_transaction_option( + self, mock_send_revoc_reg_entry, mock_create_record, _ + ): + self.profile.inject_or = mock.MagicMock() result = await self.registry.register_revocation_list( self.profile, @@ -887,10 +982,8 @@ async def test_register_revocation_list_with_create_transaction_option( ) assert isinstance(result, RevListResult) - assert self.profile.context.injector.get_provider( - BaseLedger - )._instance.send_revoc_reg_entry.called assert mock_create_record.called + assert mock_send_revoc_reg_entry.called @mock.patch.object( ConnRecord, @@ -909,17 +1002,27 @@ async def test_register_revocation_list_with_create_transaction_option( "create_request", return_value=(TransactionRecord(), "transaction_request"), ) - async def test_register_revocation_list_with_create_transaction_option_and_auto_request( - self, mock_create_request, mock_create_record, mock_endorsement_conn - ): - self.profile.context.injector.bind_instance( - BaseLedger, + @mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + return_value=( + "id", mock.MagicMock( send_revoc_reg_entry=mock.CoroutineMock( - return_value=("id", {"signed_txn": "txn"}) + return_value=( + "rev_reg_def_id", + { + "signed_txn": "txn", + }, + ) ) ), - ) + ), + ) + async def test_register_revocation_list_with_create_transaction_option_and_auto_request( + self, mock_send_revoc_reg_entry, mock_create_request, mock_create_record, _ + ): + self.profile.inject_or = mock.MagicMock() self.profile.context.injector.bind_instance( BaseResponder, mock.MagicMock(send=mock.CoroutineMock(return_value=None)), @@ -956,11 +1059,162 @@ async def test_register_revocation_list_with_create_transaction_option_and_auto_ ) assert isinstance(result, RevListResult) - assert self.profile.context.injector.get_provider( - BaseLedger - )._instance.send_revoc_reg_entry.called assert mock_create_record.called assert mock_create_request.called + assert mock_send_revoc_reg_entry.called assert self.profile.context.injector.get_provider( BaseResponder )._instance.send.called + + @mock.patch.object( + IndyLedgerRequestsExecutor, + "get_ledger_for_identifier", + return_value=( + "id", + mock.MagicMock( + get_revoc_reg_delta=mock.CoroutineMock( + return_value=( + { + "value": { + "accum": "21 124C594B6B20E41B681E92B2C43FD165EA9E68BC3C9D63A82C8893124983CAE94 21 124C5341937827427B0A3A32113BD5E64FB7AB39BD3E5ABDD7970874501CA4897 6 5438CB6F442E2F807812FD9DC0C39AFF4A86B1E6766DBB5359E86A4D70401B0F 4 39D1CA5C4716FFC4FE0853C4FF7F081DFD8DF8D2C2CA79705211680AC77BF3A1 6 70504A5493F89C97C225B68310811A41AD9CD889301F238E93C95AD085E84191 4 39582252194D756D5D86D0EED02BF1B95CE12AED2FA5CD3C53260747D891993C", + } + }, + 123, + ) + ) + ), + ), + ) + @mock.patch.object( + test_module.LegacyIndyRegistry, + "_sync_wallet_rev_list_with_issuer_cred_rev_records", + mock.CoroutineMock( + return_value=RevList( + issuer_id="CsQY9MGeD3CQP4EyuVFo5m", + current_accumulator="2 124C594B6B20E41B681E92B2C43FD165EA9E68BC3C9D63A82C8893124983CAE94 21 124C5341937827427B0A3A32113BD5E64FB7AB39BD3E5ABDD7970874501CA4897 6 5438CB6F442E2F807812FD9DC0C39AFF4A86B1E6766DBB5359E86A4D70401B0F 4 39D1CA5C4716FFC4FE0853C4FF7F081DFD8DF8D2C2CA79705211680AC77BF3A1 6 70504A5493F89C97C225B68310811A41AD9CD889301F238E93C95AD085E84191 4 39582252194D756D5D86D0EED02BF1B95CE12AED2FA5CD3C53260747D891993C", + revocation_list=[1, 0, 1, 0], + timestamp=1669640864487, + rev_reg_def_id="4xE68b6S5VRFrKMMG1U95M:4:4xE68b6S5VRFrKMMG1U95M:3:CL:59232:default:CL_ACCUM:4ae1cc6c-f6bd-486c-8057-88f2ce74e960", + ) + ), + ) + @mock.patch( + "aries_cloudagent.anoncreds.default.legacy_indy.registry.generate_ledger_rrrecovery_txn", + mock.CoroutineMock(return_value=MockTxn()), + ) + async def test_fix_ledger_entry(self, *_): + + self.profile.context.injector.bind_instance( + BaseLedger, + mock.MagicMock(send_revoc_reg_entry=mock.CoroutineMock(return_value={})), + ) + + self.profile.context.injector.bind_instance( + EventBus, + {}, + ) + + async with self.profile.transaction() as txn: + issuer_cr_rec = IssuerCredRevRecord( + state=IssuerCredRevRecord.STATE_ISSUED, + cred_ex_id="cred_ex_id", + cred_ex_version=IssuerCredRevRecord.VERSION_1, + rev_reg_id="4xE68b6S5VRFrKMMG1U95M:4:4xE68b6S5VRFrKMMG1U95M:3:CL:59232:default:CL_ACCUM:4ae1cc6c-f6bd-486c-8057-88f2ce74e960", + cred_rev_id="cred_rev_id", + ) + await issuer_cr_rec.save( + txn, + reason=("Testing"), + ) + + self.profile.inject_or = mock.MagicMock() + result = await self.registry.fix_ledger_entry( + self.profile, + RevList( + issuer_id="CsQY9MGeD3CQP4EyuVFo5m", + current_accumulator="21 124C594B6B20E41B681E92B2C43FD165EA9E68BC3C9D63A82C8893124983CAE94 21 124C5341937827427B0A3A32113BD5E64FB7AB39BD3E5ABDD7970874501CA4897 6 5438CB6F442E2F807812FD9DC0C39AFF4A86B1E6766DBB5359E86A4D70401B0F 4 39D1CA5C4716FFC4FE0853C4FF7F081DFD8DF8D2C2CA79705211680AC77BF3A1 6 70504A5493F89C97C225B68310811A41AD9CD889301F238E93C95AD085E84191 4 39582252194D756D5D86D0EED02BF1B95CE12AED2FA5CD3C53260747D891993C", + revocation_list=[0, 1, 1, 0], + timestamp=1669640864487, + rev_reg_def_id="4xE68b6S5VRFrKMMG1U95M:4:4xE68b6S5VRFrKMMG1U95M:3:CL:59232:default:CL_ACCUM:4ae1cc6c-f6bd-486c-8057-88f2ce74e960", + ), + True, + '{"reqSignature":{},"txn":{"data":{"data":{"alias":"Node1","blskey":"4N8aUNHSgjQVgkpm8nhNEfDf6txHznoYREg9kirmJrkivgL4oSEimFF6nsQ6M41QvhM2Z33nves5vfSn9n1UwNFJBYtWVnHYMATn76vLuL3zU88KyeAYcHfsih3He6UHcXDxcaecHVz6jhCYz1P2UZn2bDVruL5wXpehgBfBaLKm3Ba","blskey_pop":"RahHYiCvoNCtPTrVtP7nMC5eTYrsUA8WjXbdhNc8debh1agE9bGiJxWBXYNFbnJXoXhWFMvyqhqhRoq737YQemH5ik9oL7R4NTTCz2LEZhkgLJzB3QRQqJyBNyv7acbdHrAT8nQ9UkLbaVL9NBpnWXBTw4LEMePaSHEw66RzPNdAX1","client_ip":"172.17.0.2","client_port":9702,"node_ip":"172.17.0.2","node_port":9701,"services":["VALIDATOR"]},"dest":"Gw6pDLhcBcoQesN72qfotTgFa7cbuqZpkX3Xo6pLhPhv"},"metadata":{"from":"Th7MpTaRZVRYnPiabds81Y"},"type":"0"},"txnMetadata":{"seqNo":1,"txnId":"fea82e10e894419fe2bea7d96296a6d46f50f93f9eeda954ec461b2ed2950b62"},"ver":"1"}\n{"reqSignature":{},"txn":{"data":{"data":{"alias":"Node2","blskey":"37rAPpXVoxzKhz7d9gkUe52XuXryuLXoM6P6LbWDB7LSbG62Lsb33sfG7zqS8TK1MXwuCHj1FKNzVpsnafmqLG1vXN88rt38mNFs9TENzm4QHdBzsvCuoBnPH7rpYYDo9DZNJePaDvRvqJKByCabubJz3XXKbEeshzpz4Ma5QYpJqjk","blskey_pop":"Qr658mWZ2YC8JXGXwMDQTzuZCWF7NK9EwxphGmcBvCh6ybUuLxbG65nsX4JvD4SPNtkJ2w9ug1yLTj6fgmuDg41TgECXjLCij3RMsV8CwewBVgVN67wsA45DFWvqvLtu4rjNnE9JbdFTc1Z4WCPA3Xan44K1HoHAq9EVeaRYs8zoF5","client_ip":"172.17.0.2","client_port":9704,"node_ip":"172.17.0.2","node_port":9703,"services":["VALIDATOR"]},"dest":"8ECVSk179mjsjKRLWiQtssMLgp6EPhWXtaYyStWPSGAb"},"metadata":{"from":"EbP4aYNeTHL6q385GuVpRV"},"type":"0"},"txnMetadata":{"seqNo":2,"txnId":"1ac8aece2a18ced660fef8694b61aac3af08ba875ce3026a160acbc3a3af35fc"},"ver":"1"}\n{"reqSignature":{},"txn":{"data":{"data":{"alias":"Node3","blskey":"3WFpdbg7C5cnLYZwFZevJqhubkFALBfCBBok15GdrKMUhUjGsk3jV6QKj6MZgEubF7oqCafxNdkm7eswgA4sdKTRc82tLGzZBd6vNqU8dupzup6uYUf32KTHTPQbuUM8Yk4QFXjEf2Usu2TJcNkdgpyeUSX42u5LqdDDpNSWUK5deC5","blskey_pop":"QwDeb2CkNSx6r8QC8vGQK3GRv7Yndn84TGNijX8YXHPiagXajyfTjoR87rXUu4G4QLk2cF8NNyqWiYMus1623dELWwx57rLCFqGh7N4ZRbGDRP4fnVcaKg1BcUxQ866Ven4gw8y4N56S5HzxXNBZtLYmhGHvDtk6PFkFwCvxYrNYjh","client_ip":"172.17.0.2","client_port":9706,"node_ip":"172.17.0.2","node_port":9705,"services":["VALIDATOR"]},"dest":"DKVxG2fXXTU8yT5N7hGEbXB3dfdAnYv1JczDUHpmDxya"},"metadata":{"from":"4cU41vWW82ArfxJxHkzXPG"},"type":"0"},"txnMetadata":{"seqNo":3,"txnId":"7e9f355dffa78ed24668f0e0e369fd8c224076571c51e2ea8be5f26479edebe4"},"ver":"1"}\n{"reqSignature":{},"txn":{"data":{"data":{"alias":"Node4","blskey":"2zN3bHM1m4rLz54MJHYSwvqzPchYp8jkHswveCLAEJVcX6Mm1wHQD1SkPYMzUDTZvWvhuE6VNAkK3KxVeEmsanSmvjVkReDeBEMxeDaayjcZjFGPydyey1qxBHmTvAnBKoPydvuTAqx5f7YNNRAdeLmUi99gERUU7TD8KfAa6MpQ9bw","blskey_pop":"RPLagxaR5xdimFzwmzYnz4ZhWtYQEj8iR5ZU53T2gitPCyCHQneUn2Huc4oeLd2B2HzkGnjAff4hWTJT6C7qHYB1Mv2wU5iHHGFWkhnTX9WsEAbunJCV2qcaXScKj4tTfvdDKfLiVuU2av6hbsMztirRze7LvYBkRHV3tGwyCptsrP","client_ip":"172.17.0.2","client_port":9708,"node_ip":"172.17.0.2","node_port":9707,"services":["VALIDATOR"]},"dest":"4PS3EDQ3dW1tci1Bp6543CfuuebjFrg36kLAUcskGfaA"},"metadata":{"from":"TWwCRQRZ2ZHMJFn9TzLp7W"},"type":"0"},"txnMetadata":{"seqNo":4,"txnId":"aa5e817d7cc626170eca175822029339a444eb0ee8f0bd20d3b0b76e566fb008"},"ver":"1"}', + True, + "endorser_did", + ) + + assert isinstance(result, tuple) + + @mock.patch.object(CredentialDefinition, "load") + @mock.patch.object(RevocationRegistryDefinition, "load") + @mock.patch.object(RevocationRegistryDefinitionPrivate, "load") + @mock.patch.object( + IssuerCredRevRecord, + "query_by_ids", + return_value=[ + IssuerCredRevRecord( + state=IssuerCredRevRecord.STATE_REVOKED, + cred_ex_id="cred_ex_id", + rev_reg_id="4xE68b6S5VRFrKMMG1U95M:4:4xE68b6S5VRFrKMMG1U95M:3:CL:59232:default:CL_ACCUM:4ae1cc6c-f6bd-486c-8057-88f2ce74e960", + cred_rev_id="1", + ), + IssuerCredRevRecord( + state=IssuerCredRevRecord.STATE_REVOKED, + cred_ex_id="cred_ex_id", + rev_reg_id="4xE68b6S5VRFrKMMG1U95M:5:4xE68b6S5VRFrKMMG1U95M:3:CL:59232:default:CL_ACCUM:4ae1cc6c-f6bd-486c-8057-88f2ce74e960", + cred_rev_id="2", + ), + ], + ) + @mock.patch.object( + RevList, + "to_native", + return_value=mock.MagicMock( + update=mock.MagicMock(return_value=MockRevListEntry()) + ), + ) + @mock.patch.object(InMemoryProfileSession, "handle") + async def test_sync_wallet_rev_list_with_issuer_cred_rev_records( + self, mock_handle, *_ + ): + async with self.profile.session() as session: + # Matching revocations and rev_list + mock_handle.fetch = mock.CoroutineMock( + side_effect=[ + MockRevRegDefEntry(), + MockCredDefEntry(), + mock.CoroutineMock(return_value=None), + ] + ) + result = await self.registry._sync_wallet_rev_list_with_issuer_cred_rev_records( + session, + RevList( + issuer_id="CsQY9MGeD3CQP4EyuVFo5m", + current_accumulator="21 124C594B6B20E41B681E92B2C43FD165EA9E68BC3C9D63A82C8893124983CAE94 21 124C5341937827427B0A3A32113BD5E64FB7AB39BD3E5ABDD7970874501CA4897 6 5438CB6F442E2F807812FD9DC0C39AFF4A86B1E6766DBB5359E86A4D70401B0F 4 39D1CA5C4716FFC4FE0853C4FF7F081DFD8DF8D2C2CA79705211680AC77BF3A1 6 70504A5493F89C97C225B68310811A41AD9CD889301F238E93C95AD085E84191 4 39582252194D756D5D86D0EED02BF1B95CE12AED2FA5CD3C53260747D891993C", + revocation_list=[0, 1, 1, 0], + timestamp=1669640864487, + rev_reg_def_id="4xE68b6S5VRFrKMMG1U95M:4:4xE68b6S5VRFrKMMG1U95M:3:CL:59232:default:CL_ACCUM:4ae1cc6c-f6bd-486c-8057-88f2ce74e960", + ), + ) + assert isinstance(result, RevList) + # Non-matching revocations and rev_list + mock_handle.fetch = mock.CoroutineMock( + side_effect=[ + MockRevRegDefEntry(), + MockCredDefEntry(), + mock.CoroutineMock(return_value=None), + MockRevListEntry(), + ] + ) + mock_handle.replace = mock.CoroutineMock(return_value=None) + result = await self.registry._sync_wallet_rev_list_with_issuer_cred_rev_records( + session, + RevList( + issuer_id="CsQY9MGeD3CQP4EyuVFo5m", + current_accumulator="21 124C594B6B20E41B681E92B2C43FD165EA9E68BC3C9D63A82C8893124983CAE94 21 124C5341937827427B0A3A32113BD5E64FB7AB39BD3E5ABDD7970874501CA4897 6 5438CB6F442E2F807812FD9DC0C39AFF4A86B1E6766DBB5359E86A4D70401B0F 4 39D1CA5C4716FFC4FE0853C4FF7F081DFD8DF8D2C2CA79705211680AC77BF3A1 6 70504A5493F89C97C225B68310811A41AD9CD889301F238E93C95AD085E84191 4 39582252194D756D5D86D0EED02BF1B95CE12AED2FA5CD3C53260747D891993C", + revocation_list=[0, 1, 0, 0], + timestamp=1669640864487, + rev_reg_def_id="4xE68b6S5VRFrKMMG1U95M:4:4xE68b6S5VRFrKMMG1U95M:3:CL:59232:default:CL_ACCUM:4ae1cc6c-f6bd-486c-8057-88f2ce74e960", + ), + ) + assert isinstance(result, RevList) diff --git a/aries_cloudagent/anoncreds/revocation.py b/aries_cloudagent/anoncreds/revocation.py index 84a03ef866..a5d49e0dbb 100644 --- a/aries_cloudagent/anoncreds/revocation.py +++ b/aries_cloudagent/anoncreds/revocation.py @@ -577,7 +577,7 @@ async def update_revocation_list( self.profile, rev_reg_def, prev, curr, revoked, options ) - # # TODO Handle `failed` state + # TODO Handle `failed` state try: async with self.profile.session() as session: rev_list_entry_upd = await session.handle.fetch( @@ -1284,7 +1284,7 @@ async def revoke_pending_credentials( for rev_id in cred_revoc_ids: if rev_id < 1 or rev_id > max_cred_num: LOGGER.error( - "Skipping requested credential revocation" + "Skipping requested credential revocation " "on rev reg id %s, cred rev id=%s not in range", revoc_reg_id, rev_id, @@ -1292,7 +1292,7 @@ async def revoke_pending_credentials( failed_crids.add(rev_id) elif rev_id >= rev_info["next_index"]: LOGGER.warning( - "Skipping requested credential revocation" + "Skipping requested credential revocation " "on rev reg id %s, cred rev id=%s not yet issued", revoc_reg_id, rev_id, @@ -1300,7 +1300,7 @@ async def revoke_pending_credentials( failed_crids.add(rev_id) elif rev_list.revocation_list[rev_id] == 1: LOGGER.warning( - "Skipping requested credential revocation" + "Skipping requested credential revocation " "on rev reg id %s, cred rev id=%s already revoked", revoc_reg_id, rev_id, diff --git a/aries_cloudagent/revocation_anoncreds/routes.py b/aries_cloudagent/revocation_anoncreds/routes.py index e6cf3ec7e7..327627db96 100644 --- a/aries_cloudagent/revocation_anoncreds/routes.py +++ b/aries_cloudagent/revocation_anoncreds/routes.py @@ -883,6 +883,7 @@ async def update_rev_reg_revoked_state(request: web.BaseRequest): apply_ledger_update = json.loads(request.query.get("apply_ledger_update", "false")) genesis_transactions = None + recovery_txn = {} try: revocation = AnonCredsRevocation(profile) rev_reg_def = await revocation.get_created_revocation_registry_definition( @@ -944,8 +945,8 @@ async def update_rev_reg_revoked_state(request: web.BaseRequest): return web.json_response( { "rev_reg_delta": rev_reg_delta, - "accum_calculated": recovery_txn, - "accum_fixed": applied_txn, + "recovery_txn": recovery_txn, + "applied_txn": applied_txn, } ) From 10234e70f440535f2559b17c114ca426b846553b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 18 Jun 2024 12:11:08 -0700 Subject: [PATCH 12/12] chore(deps): Bump the pip group with 2 updates (#3046) Bumps the pip group with 2 updates: [requests](https://github.com/psf/requests) and [urllib3](https://github.com/urllib3/urllib3). Updates `requests` from 2.31.0 to 2.32.2 - [Release notes](https://github.com/psf/requests/releases) - [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md) - [Commits](https://github.com/psf/requests/compare/v2.31.0...v2.32.2) Updates `urllib3` from 2.2.1 to 2.2.2 - [Release notes](https://github.com/urllib3/urllib3/releases) - [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst) - [Commits](https://github.com/urllib3/urllib3/compare/2.2.1...2.2.2) --- updated-dependencies: - dependency-name: requests dependency-type: direct:production dependency-group: pip - dependency-name: urllib3 dependency-type: indirect dependency-group: pip ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: jamshale <31809382+jamshale@users.noreply.github.com> --- poetry.lock | 16 ++++++++-------- pyproject.toml | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/poetry.lock b/poetry.lock index eaa5130a3e..3cca935e01 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2342,13 +2342,13 @@ test = ["mock", "pytest", "pytest-cov"] [[package]] name = "requests" -version = "2.31.0" +version = "2.32.2" description = "Python HTTP for Humans." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, - {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, + {file = "requests-2.32.2-py3-none-any.whl", hash = "sha256:fc06670dd0ed212426dfeb94fc1b983d917c4f9847c863f313c9dfaaffb7c23c"}, + {file = "requests-2.32.2.tar.gz", hash = "sha256:dd951ff5ecf3e3b3aa26b40703ba77495dab41da839ae72ef3c8e5d8e2433289"}, ] [package.dependencies] @@ -2586,13 +2586,13 @@ files = [ [[package]] name = "urllib3" -version = "2.2.1" +version = "2.2.2" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.8" files = [ - {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, - {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, + {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, + {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, ] [package.extras] @@ -2883,4 +2883,4 @@ bbs = ["ursa-bbs-signatures"] [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "68ee696d9d85f76bc11c3de934af0469b55417504eeac443ca81bdb5bb9cb0a3" +content-hash = "4b6f2549e72f9633abd0bdb83f17d839f6fd6d75bf9fc6c60a5581b8886d5712" diff --git a/pyproject.toml b/pyproject.toml index 4b78512b0b..d43eb34852 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ python-dateutil="~2.8.1" python-json-logger="~2.0.7" pyyaml="~6.0.1" qrcode = {version = ">=6.1,<7.0", extras = ["pil"]} -requests="~2.31.0" +requests="~2.32.2" rlp="4.0.1" unflatten="~0.1" sd-jwt = "^0.10.3"